From f8758c6902ed725864ff677f739829aa6bce2078 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 16 May 2024 14:05:21 -0700 Subject: [PATCH 001/335] Implement functions resource detector (#2523) * Update .pylintrc * fn * Update CHANGELOG.md * commments * Add deployment.environment to functions detector * Revert "Add deployment.environment to functions detector" This reverts commit 5411759711b8bc9976705deb416d5ffd8f65590f. * Remove deployment.environment from readme * Release 0.1.5 --------- Co-authored-by: jeremydvoss --- .../CHANGELOG.md | 4 +- .../README.rst | 12 +- .../pyproject.toml | 1 + .../resource/detector/azure/__init__.py | 2 + .../resource/detector/azure/_constants.py | 6 + .../resource/detector/azure/_utils.py | 27 ++++- .../resource/detector/azure/app_service.py | 32 ++--- .../resource/detector/azure/functions.py | 68 +++++++++++ .../resource/detector/azure/version.py | 2 +- .../tests/test_app_service.py | 39 +++++++ .../tests/test_functions.py | 110 ++++++++++++++++++ 11 files changed, 274 insertions(+), 29 deletions(-) create mode 100644 resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py create mode 100644 resource/opentelemetry-resource-detector-azure/tests/test_functions.py diff --git a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md index 8954fc5359..f77fce18f1 100644 --- a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md +++ b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md @@ -5,10 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## Version 0.1.5 (2024-05-16) - Ignore vm detector if already in other rps ([#2456](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2456)) +- Implement functions resource detector + ([#2523](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2523)) ## Version 0.1.4 (2024-04-05) diff --git a/resource/opentelemetry-resource-detector-azure/README.rst b/resource/opentelemetry-resource-detector-azure/README.rst index 6a376534ad..baf2dddbbe 100644 --- a/resource/opentelemetry-resource-detector-azure/README.rst +++ b/resource/opentelemetry-resource-detector-azure/README.rst @@ -60,7 +60,17 @@ The Azure App Service Resource Detector sets the following Resource Attributes: * ``service.instance.id`` set to the value of the ``WEBSITE_INSTANCE_ID`` environment variable. * ``azure.app.service.stamp`` set to the value of the ``WEBSITE_HOME_STAMPNAME`` environment variable. -The Azure VM Resource Detector sets the following Resource Attributes according to the response from the `Azure Metadata Service `_: + The Azure Functions Resource Detector sets the following Resource Attributes: + * ``service.name`` set to the value of the ``WEBSITE_SITE_NAME`` environment variable. + * ``process.id`` set to the process ID collected from the running process. + * ``cloud.platform`` set to ``azure_functions``. + * ``cloud.provider`` set to ``azure``. + * ``cloud.resource_id`` set using the ``WEBSITE_RESOURCE_GROUP``, ``WEBSITE_OWNER_NAME``, and ``WEBSITE_SITE_NAME`` environment variables. + * ``cloud.region`` set to the value of the ``REGION_NAME`` environment variable. + * ``faas.instance`` set to the value of the ``WEBSITE_INSTANCE_ID`` environment variable. + * ``faas.max_memory`` set to the value of the ``WEBSITE_MEMORY_LIMIT_MB`` environment variable. + +The Azure VM Resource Detector sets the following Resource Attributes according to the response from the `Azure Metadata Service `_: * ``azure.vm.scaleset.name`` set to the value of the ``vmScaleSetName`` field. * ``azure.vm.sku`` set to the value of the ``sku`` field. * ``cloud.platform`` set to the value of the ``azure_vm``. diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index 72260709f9..efa1b24ee7 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ [project.entry-points.opentelemetry_resource_detector] azure_app_service = "opentelemetry.resource.detector.azure.app_service:AzureAppServiceResourceDetector" +azure_functions = "opentelemetry.resource.detector.azure.functions:AzureFunctionsResourceDetector" azure_vm = "opentelemetry.resource.detector.azure.vm:AzureVMResourceDetector" [project.urls] diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py index 913b677c3e..628a8ab781 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py @@ -15,11 +15,13 @@ # pylint: disable=import-error from .app_service import AzureAppServiceResourceDetector +from .functions import AzureFunctionsResourceDetector from .version import __version__ from .vm import AzureVMResourceDetector __all__ = [ "AzureAppServiceResourceDetector", + "AzureFunctionsResourceDetector", "AzureVMResourceDetector", "__version__", ] diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py index dddc6632ac..3a6415e0d5 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py @@ -43,6 +43,12 @@ # Functions _FUNCTIONS_WORKER_RUNTIME = "FUNCTIONS_WORKER_RUNTIME" +_WEBSITE_MEMORY_LIMIT_MB = "WEBSITE_MEMORY_LIMIT_MB" + +_FUNCTIONS_ATTRIBUTE_ENV_VARS = { + ResourceAttributes.FAAS_INSTANCE: _WEBSITE_INSTANCE_ID, + ResourceAttributes.FAAS_MAX_MEMORY: _WEBSITE_MEMORY_LIMIT_MB, +} # Vm diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py index 3f73613945..62d00c5a6c 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py @@ -11,27 +11,44 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -import os +from os import environ +from typing import Optional from ._constants import ( _AKS_ARM_NAMESPACE_ID, _FUNCTIONS_WORKER_RUNTIME, + _WEBSITE_OWNER_NAME, + _WEBSITE_RESOURCE_GROUP, _WEBSITE_SITE_NAME, ) def _is_on_aks() -> bool: - return os.environ.get(_AKS_ARM_NAMESPACE_ID) is not None + return environ.get(_AKS_ARM_NAMESPACE_ID) is not None def _is_on_app_service() -> bool: - return os.environ.get(_WEBSITE_SITE_NAME) is not None + return environ.get(_WEBSITE_SITE_NAME) is not None def _is_on_functions() -> bool: - return os.environ.get(_FUNCTIONS_WORKER_RUNTIME) is not None + return environ.get(_FUNCTIONS_WORKER_RUNTIME) is not None def _can_ignore_vm_detect() -> bool: return _is_on_aks() or _is_on_app_service() or _is_on_functions() + + +def _get_azure_resource_uri() -> Optional[str]: + website_site_name = environ.get(_WEBSITE_SITE_NAME) + website_resource_group = environ.get(_WEBSITE_RESOURCE_GROUP) + website_owner_name = environ.get(_WEBSITE_OWNER_NAME) + + subscription_id = website_owner_name + if website_owner_name and "+" in website_owner_name: + subscription_id = website_owner_name[0 : website_owner_name.index("+")] + + if not (website_site_name and website_resource_group and subscription_id): + return None + + return f"/subscriptions/{subscription_id}/resourceGroups/{website_resource_group}/providers/Microsoft.Web/sites/{website_site_name}" diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py index 613d8f9410..41371b8eec 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Optional from os import environ from opentelemetry.sdk.resources import Resource, ResourceDetector @@ -20,29 +21,32 @@ CloudProviderValues, ResourceAttributes, ) +from opentelemetry.resource.detector.azure._utils import _get_azure_resource_uri from ._constants import ( _APP_SERVICE_ATTRIBUTE_ENV_VARS, - _WEBSITE_OWNER_NAME, - _WEBSITE_RESOURCE_GROUP, _WEBSITE_SITE_NAME, ) +from opentelemetry.resource.detector.azure._utils import _is_on_functions + class AzureAppServiceResourceDetector(ResourceDetector): def detect(self) -> Resource: attributes = {} website_site_name = environ.get(_WEBSITE_SITE_NAME) if website_site_name: - attributes[ResourceAttributes.SERVICE_NAME] = website_site_name + # Functions resource detector takes priority with `service.name` and `cloud.platform` + if not _is_on_functions(): + attributes[ResourceAttributes.SERVICE_NAME] = website_site_name + attributes[ResourceAttributes.CLOUD_PLATFORM] = ( + CloudPlatformValues.AZURE_APP_SERVICE.value + ) attributes[ResourceAttributes.CLOUD_PROVIDER] = ( CloudProviderValues.AZURE.value ) - attributes[ResourceAttributes.CLOUD_PLATFORM] = ( - CloudPlatformValues.AZURE_APP_SERVICE.value - ) - azure_resource_uri = _get_azure_resource_uri(website_site_name) + azure_resource_uri = _get_azure_resource_uri() if azure_resource_uri: attributes[ResourceAttributes.CLOUD_RESOURCE_ID] = ( azure_resource_uri @@ -53,17 +57,3 @@ def detect(self) -> Resource: attributes[key] = value return Resource(attributes) - - -def _get_azure_resource_uri(website_site_name): - website_resource_group = environ.get(_WEBSITE_RESOURCE_GROUP) - website_owner_name = environ.get(_WEBSITE_OWNER_NAME) - - subscription_id = website_owner_name - if website_owner_name and "+" in website_owner_name: - subscription_id = website_owner_name[0 : website_owner_name.index("+")] - - if not (website_resource_group and subscription_id): - return None - - return f"/subscriptions/{subscription_id}/resourceGroups/{website_resource_group}/providers/Microsoft.Web/sites/{website_site_name}" diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py new file mode 100644 index 0000000000..0bf9a10f86 --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py @@ -0,0 +1,68 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from os import environ, getpid + +from opentelemetry.sdk.resources import Resource, ResourceDetector +from opentelemetry.semconv.resource import ( + CloudPlatformValues, + CloudProviderValues, + ResourceAttributes, +) + +from ._constants import ( + _FUNCTIONS_ATTRIBUTE_ENV_VARS, + _REGION_NAME, + _WEBSITE_SITE_NAME, +) +from opentelemetry.resource.detector.azure._utils import ( + _get_azure_resource_uri, + _is_on_functions, +) + + +class AzureFunctionsResourceDetector(ResourceDetector): + def detect(self) -> Resource: + attributes = {} + if _is_on_functions(): + website_site_name = environ.get(_WEBSITE_SITE_NAME) + if website_site_name: + attributes[ResourceAttributes.SERVICE_NAME] = website_site_name + attributes[ResourceAttributes.PROCESS_PID] = getpid() + attributes[ResourceAttributes.CLOUD_PROVIDER] = ( + CloudProviderValues.AZURE.value + ) + attributes[ResourceAttributes.CLOUD_PLATFORM] = ( + CloudPlatformValues.AZURE_FUNCTIONS.value + ) + cloud_region = environ.get(_REGION_NAME) + if cloud_region: + attributes[ResourceAttributes.CLOUD_REGION] = cloud_region + azure_resource_uri = _get_azure_resource_uri() + if azure_resource_uri: + attributes[ResourceAttributes.CLOUD_RESOURCE_ID] = ( + azure_resource_uri + ) + for key, env_var in _FUNCTIONS_ATTRIBUTE_ENV_VARS.items(): + value = environ.get(env_var) + if value: + if key == ResourceAttributes.FAAS_MAX_MEMORY: + try: + value = int(value) + except ValueError: + continue + attributes[key] = value + + return Resource(attributes) + diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py index f961659f70..fac29d773f 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.1.4" +__version__ = "0.1.5" diff --git a/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py b/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py index c5d2396dab..6c3d395994 100644 --- a/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py +++ b/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py @@ -68,6 +68,45 @@ def test_on_app_service(self): self.assertEqual( attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME ) + + @patch.dict( + "os.environ", + { + "FUNCTIONS_WORKER_RUNTIME": "1", + "WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME, + "REGION_NAME": TEST_REGION_NAME, + "WEBSITE_SLOT_NAME": TEST_WEBSITE_SLOT_NAME, + "WEBSITE_HOSTNAME": TEST_WEBSITE_HOSTNAME, + "WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID, + "WEBSITE_HOME_STAMPNAME": TEST_WEBSITE_HOME_STAMPNAME, + "WEBSITE_RESOURCE_GROUP": TEST_WEBSITE_RESOURCE_GROUP, + "WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME, + }, + clear=True, + ) + def test_on_app_service_with_functions(self): + resource = AzureAppServiceResourceDetector().detect() + attributes = resource.attributes + self.assertIsNone(attributes.get("service.name")) + self.assertEqual(attributes["cloud.provider"], "azure") + self.assertIsNone(attributes.get("cloud.platform")) + + self.assertEqual( + attributes["cloud.resource_id"], + f"/subscriptions/{TEST_WEBSITE_OWNER_NAME}/resourceGroups/{TEST_WEBSITE_RESOURCE_GROUP}/providers/Microsoft.Web/sites/{TEST_WEBSITE_SITE_NAME}", + ) + + self.assertEqual(attributes["cloud.region"], TEST_REGION_NAME) + self.assertEqual( + attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME + ) + self.assertEqual(attributes["host.id"], TEST_WEBSITE_HOSTNAME) + self.assertEqual( + attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID + ) + self.assertEqual( + attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME + ) @patch.dict( "os.environ", diff --git a/resource/opentelemetry-resource-detector-azure/tests/test_functions.py b/resource/opentelemetry-resource-detector-azure/tests/test_functions.py new file mode 100644 index 0000000000..1f5354c500 --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/tests/test_functions.py @@ -0,0 +1,110 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest +from unittest.mock import patch + +# pylint: disable=no-name-in-module +from opentelemetry.resource.detector.azure.functions import ( + AzureFunctionsResourceDetector, +) + +TEST_WEBSITE_SITE_NAME = "TEST_WEBSITE_SITE_NAME" +TEST_REGION_NAME = "TEST_REGION_NAME" +TEST_WEBSITE_INSTANCE_ID = "TEST_WEBSITE_INSTANCE_ID" + +TEST_WEBSITE_RESOURCE_GROUP = "TEST_WEBSITE_RESOURCE_GROUP" +TEST_WEBSITE_OWNER_NAME = "TEST_WEBSITE_OWNER_NAME" +TEST_WEBSITE_MEMORY_LIMIT_MB = "1024" + + +class TestAzureAppServiceResourceDetector(unittest.TestCase): + @patch.dict( + "os.environ", + { + "FUNCTIONS_WORKER_RUNTIME": "1", + "WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME, + "REGION_NAME": TEST_REGION_NAME, + "WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID, + "WEBSITE_RESOURCE_GROUP": TEST_WEBSITE_RESOURCE_GROUP, + "WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME, + "WEBSITE_MEMORY_LIMIT_MB": TEST_WEBSITE_MEMORY_LIMIT_MB, + }, + clear=True, + ) + @patch("opentelemetry.resource.detector.azure.functions.getpid") + def test_on_functions(self, pid_mock): + pid_mock.return_value = 1000 + resource = AzureFunctionsResourceDetector().detect() + attributes = resource.attributes + self.assertEqual(attributes["service.name"], TEST_WEBSITE_SITE_NAME) + self.assertEqual(attributes["cloud.provider"], "azure") + self.assertEqual(attributes["cloud.platform"], "azure_functions") + self.assertEqual(attributes["process.pid"], 1000) + + self.assertEqual( + attributes["cloud.resource_id"], + f"/subscriptions/{TEST_WEBSITE_OWNER_NAME}/resourceGroups/{TEST_WEBSITE_RESOURCE_GROUP}/providers/Microsoft.Web/sites/{TEST_WEBSITE_SITE_NAME}", + ) + + self.assertEqual(attributes["cloud.region"], TEST_REGION_NAME) + self.assertEqual(attributes["faas.instance"], TEST_WEBSITE_INSTANCE_ID) + self.assertEqual(attributes["faas.max_memory"], 1024) + + @patch.dict( + "os.environ", + { + "FUNCTIONS_WORKER_RUNTIME": "1", + "WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME, + "REGION_NAME": TEST_REGION_NAME, + "WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID, + "WEBSITE_RESOURCE_GROUP": TEST_WEBSITE_RESOURCE_GROUP, + "WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME, + "WEBSITE_MEMORY_LIMIT_MB": "error", + }, + clear=True, + ) + @patch("opentelemetry.resource.detector.azure.functions.getpid") + def test_on_functions_error_memory(self, pid_mock): + pid_mock.return_value = 1000 + resource = AzureFunctionsResourceDetector().detect() + attributes = resource.attributes + self.assertEqual(attributes["service.name"], TEST_WEBSITE_SITE_NAME) + self.assertEqual(attributes["cloud.provider"], "azure") + self.assertEqual(attributes["cloud.platform"], "azure_functions") + self.assertEqual(attributes["process.pid"], 1000) + + self.assertEqual( + attributes["cloud.resource_id"], + f"/subscriptions/{TEST_WEBSITE_OWNER_NAME}/resourceGroups/{TEST_WEBSITE_RESOURCE_GROUP}/providers/Microsoft.Web/sites/{TEST_WEBSITE_SITE_NAME}", + ) + + self.assertEqual(attributes["cloud.region"], TEST_REGION_NAME) + self.assertEqual(attributes["faas.instance"], TEST_WEBSITE_INSTANCE_ID) + self.assertIsNone(attributes.get("faas.max_memory")) + + @patch.dict( + "os.environ", + { + "WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME, + "REGION_NAME": TEST_REGION_NAME, + "WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID, + "WEBSITE_RESOURCE_GROUP": TEST_WEBSITE_RESOURCE_GROUP, + "WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME, + "WEBSITE_MEMORY_LIMIT_MB": TEST_WEBSITE_MEMORY_LIMIT_MB, + }, + clear=True, + ) + def test_off_app_service(self): + resource = AzureFunctionsResourceDetector().detect() + self.assertEqual(resource.attributes, {}) From f4f3042f85fa68565c4da3f96d437b15d78e1063 Mon Sep 17 00:00:00 2001 From: Povilas Versockas Date: Wed, 22 May 2024 07:48:54 +0300 Subject: [PATCH 002/335] fix(async-io): check for __name__ atribute when tracing coroutine (#2521) --- CHANGELOG.md | 2 + .../instrumentation/asyncio/__init__.py | 2 + .../tests/test_asyncio_anext.py | 56 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py diff --git a/CHANGELOG.md b/CHANGELOG.md index d10983c10b..b963cfddc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2474](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2474)) - `opentelemetry-instrumentation-elasticsearch` Improved support for version 8 ([#2420](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2420)) +- `opentelemetry-instrumentation-asyncio` Check for __name__ attribute in the coroutine + ([#2521](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2521)) ## Version 1.24.0/0.45b0 (2024-03-28) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index 72aa5fd2aa..6d82da6cd0 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -261,6 +261,8 @@ def trace_item(self, coro_or_future): return coro_or_future async def trace_coroutine(self, coro): + if not hasattr(coro, "__name__"): + return start = default_timer() attr = { "type": "coroutine", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py new file mode 100644 index 0000000000..9ce3fc4b33 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -0,0 +1,56 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import asyncio +from unittest.mock import patch + +# pylint: disable=no-name-in-module +from opentelemetry.instrumentation.asyncio import AsyncioInstrumentor +from opentelemetry.instrumentation.asyncio.environment_variables import ( + OTEL_PYTHON_ASYNCIO_COROUTINE_NAMES_TO_TRACE, +) +from opentelemetry.test.test_base import TestBase +from opentelemetry.trace import get_tracer + + +class TestAsyncioAnext(TestBase): + @patch.dict( + "os.environ", + {OTEL_PYTHON_ASYNCIO_COROUTINE_NAMES_TO_TRACE: "async_func"}, + ) + def setUp(self): + super().setUp() + AsyncioInstrumentor().instrument() + self._tracer = get_tracer( + __name__, + ) + + def tearDown(self): + super().tearDown() + AsyncioInstrumentor().uninstrument() + + # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced. + # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute. + def test_asyncio_anext(self): + async def main(): + async def async_gen(): + for it in range(2): + yield it + + async_gen_instance = async_gen() + agen = anext(async_gen_instance) + await asyncio.create_task(agen) + + asyncio.run(main()) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) From c28f9b837f386cffd9b0f8800f7653a85ca5c60e Mon Sep 17 00:00:00 2001 From: Jeremy Voss Date: Wed, 22 May 2024 10:45:10 -0700 Subject: [PATCH 003/335] Update functions detector readme (#2533) --- .../README.rst | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/resource/opentelemetry-resource-detector-azure/README.rst b/resource/opentelemetry-resource-detector-azure/README.rst index baf2dddbbe..19a0f97f32 100644 --- a/resource/opentelemetry-resource-detector-azure/README.rst +++ b/resource/opentelemetry-resource-detector-azure/README.rst @@ -9,6 +9,7 @@ OpenTelemetry Resource detectors for Azure This library contains OpenTelemetry `Resource Detectors `_ for the following Azure resources: * `Azure App Service `_ * `Azure Virtual Machines `_ + * `Azure Functions (Experimental) `_ Installation ------------ @@ -60,16 +61,6 @@ The Azure App Service Resource Detector sets the following Resource Attributes: * ``service.instance.id`` set to the value of the ``WEBSITE_INSTANCE_ID`` environment variable. * ``azure.app.service.stamp`` set to the value of the ``WEBSITE_HOME_STAMPNAME`` environment variable. - The Azure Functions Resource Detector sets the following Resource Attributes: - * ``service.name`` set to the value of the ``WEBSITE_SITE_NAME`` environment variable. - * ``process.id`` set to the process ID collected from the running process. - * ``cloud.platform`` set to ``azure_functions``. - * ``cloud.provider`` set to ``azure``. - * ``cloud.resource_id`` set using the ``WEBSITE_RESOURCE_GROUP``, ``WEBSITE_OWNER_NAME``, and ``WEBSITE_SITE_NAME`` environment variables. - * ``cloud.region`` set to the value of the ``REGION_NAME`` environment variable. - * ``faas.instance`` set to the value of the ``WEBSITE_INSTANCE_ID`` environment variable. - * ``faas.max_memory`` set to the value of the ``WEBSITE_MEMORY_LIMIT_MB`` environment variable. - The Azure VM Resource Detector sets the following Resource Attributes according to the response from the `Azure Metadata Service `_: * ``azure.vm.scaleset.name`` set to the value of the ``vmScaleSetName`` field. * ``azure.vm.sku`` set to the value of the ``sku`` field. @@ -84,6 +75,16 @@ The Azure VM Resource Detector sets the following Resource Attributes according * ``os.version`` set to the value of the ``version`` field. * ``service.instance.id`` set to the value of the ``vmId`` field. +The Azure Functions Resource Detector is currently experimental. It sets the following Resource Attributes: + * ``service.name`` set to the value of the ``WEBSITE_SITE_NAME`` environment variable. + * ``process.id`` set to the process ID collected from the running process. + * ``cloud.platform`` set to ``azure_functions``. + * ``cloud.provider`` set to ``azure``. + * ``cloud.resource_id`` set using the ``WEBSITE_RESOURCE_GROUP``, ``WEBSITE_OWNER_NAME``, and ``WEBSITE_SITE_NAME`` environment variables. + * ``cloud.region`` set to the value of the ``REGION_NAME`` environment variable. + * ``faas.instance`` set to the value of the ``WEBSITE_INSTANCE_ID`` environment variable. + * ``faas.max_memory`` set to the value of the ``WEBSITE_MEMORY_LIMIT_MB`` environment variable. + For more information, see the `Semantic Conventions for Cloud Resource Attributes `_. References From da75015fade9f8adf58416fdeb8684a4a263d7b8 Mon Sep 17 00:00:00 2001 From: Adin Hodovic Date: Thu, 23 May 2024 11:02:46 +0200 Subject: [PATCH 004/335] fix: Ensure compability with Psycopg3 to extract libpq build version (#2500) * fix: Ensure compability with Psycopg3 to extract libpq build version Struggling with getting dbapi and psycopg3 working. Think this is the error, __libpq_version does not exist on psycopg3 https://github.com/psycopg/psycopg/blob/master/psycopg/psycopg/pq/pq_ctypes.py#L1220 * docs: Add changelog entry * docs: Fix spelling --------- Co-authored-by: Riccardo Magliocchetti Co-authored-by: Shalev Roda <65566801+shalevr@users.noreply.github.com> --- CHANGELOG.md | 4 +-- .../instrumentation/dbapi/__init__.py | 9 ++++++- .../tests/test_dbapi_integration.py | 26 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b963cfddc2..038706f35c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version (#2500)[https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500] - `opentelemetry-instrumentation-grpc` AioClientInterceptor should propagate with a Metadata object ([#2363](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2363)) - `opentelemetry-instrumentation-boto3sqs` Instrument Session and resource @@ -126,7 +127,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1959](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1959)) - `opentelemetry-resource-detector-azure` Added dependency for Cloud Resource ID attribute ([#2072](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2072)) - + ## Version 1.21.0/0.42b0 (2023-11-01) ### Added @@ -1540,4 +1541,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-resource-detector-azure` Suppress instrumentation for `urllib` call ([#2178](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2178)) - AwsLambdaInstrumentor handles and re-raises function exception ([#2245](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2245)) - diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index b0acbed185..0857d2989b 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -427,12 +427,19 @@ def traced_execution( if args and self._commenter_enabled: try: args_list = list(args) + if hasattr(self._connect_module, "__libpq_version__"): + libpq_version = self._connect_module.__libpq_version__ + else: + libpq_version = ( + self._connect_module.pq.__build_version__ + ) + commenter_data = { # Psycopg2/framework information "db_driver": f"psycopg2:{self._connect_module.__version__.split(' ')[0]}", "dbapi_threadsafety": self._connect_module.threadsafety, "dbapi_level": self._connect_module.apilevel, - "libpq_version": self._connect_module.__libpq_version__, + "libpq_version": libpq_version, "driver_paramstyle": self._connect_module.paramstyle, } if self._commenter_options.get( diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index 0d19ce8373..d0835e93e6 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -275,6 +275,32 @@ def test_executemany_comment(self): r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + def test_compatible_build_version_psycopg_psycopg2_libpq(self): + connect_module = mock.MagicMock() + connect_module.__version__ = mock.MagicMock() + connect_module.pq = mock.MagicMock() + connect_module.pq.__build_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "testcomponent", + enable_commenter=True, + commenter_options={"db_driver": False, "dbapi_level": False}, + connect_module=connect_module, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + def test_executemany_flask_integration_comment(self): connect_module = mock.MagicMock() connect_module.__version__ = mock.MagicMock() From 66a107fa49fc6d264ae6d690c09c9f04bc4a5dd7 Mon Sep 17 00:00:00 2001 From: Povilas Versockas Date: Fri, 24 May 2024 02:28:50 +0300 Subject: [PATCH 005/335] fix(async-io): return coro when __name__ is not present (#2541) --- .../src/opentelemetry/instrumentation/asyncio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index 6d82da6cd0..fc1b535270 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -262,7 +262,7 @@ def trace_item(self, coro_or_future): async def trace_coroutine(self, coro): if not hasattr(coro, "__name__"): - return + return coro start = default_timer() attr = { "type": "coroutine", From 78285a5795db18e25126f1452a92a536a611b1be Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Fri, 24 May 2024 10:49:18 -0700 Subject: [PATCH 006/335] Pin codespell version to fix builds (#2550) --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index fecc9e5af7..0f1e8badcc 100644 --- a/tox.ini +++ b/tox.ini @@ -1206,7 +1206,7 @@ commands = basepython: python3 recreate = True deps = - codespell + codespell==2.2.6 commands = codespell From c1a51fde96c0f53ca185c3816be9fe69cba4f528 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 24 May 2024 19:57:29 +0200 Subject: [PATCH 007/335] Pre Python 3.12 enablement fixes (#2529) --- .../test-requirements.txt | 2 +- .../tests/test_botocore_dynamodb.py | 12 ++++++------ .../tests/test_utils.py | 2 +- tox.ini | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index 9dcf9f9c0d..7c11b1e063 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -28,7 +28,7 @@ jsonschema==4.21.1 jsonschema-specifications==2023.12.1 junit-xml==1.9 MarkupSafe==2.0.1 -moto==2.2.20 +moto==3.1.19 mpmath==1.3.0 networkx==3.1 packaging==23.2 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py index 1b7f5bb0cb..12ebe8f2b7 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py @@ -324,14 +324,14 @@ def test_get_item(self): Key={"id": {"S": "1"}}, ConsistentRead=True, AttributesToGet=["id"], - ProjectionExpression="1,2", + ProjectionExpression="PE", ReturnConsumedCapacity="TOTAL", ) span = self.assert_span("GetItem") self.assert_table_names(span, self.default_table_name) self.assert_consistent_read(span, True) - self.assert_projection(span, "1,2") + self.assert_projection(span, "PE") self.assert_consumed_capacity(span, self.default_table_name) @mock_dynamodb2 @@ -390,7 +390,7 @@ def test_query(self): } }, ScanIndexForward=True, - ProjectionExpression="1,2", + ProjectionExpression="PE", ReturnConsumedCapacity="TOTAL", ) @@ -403,7 +403,7 @@ def test_query(self): self.assert_consistent_read(span, True) self.assert_index_name(span, "lsi") self.assert_limit(span, 42) - self.assert_projection(span, "1,2") + self.assert_projection(span, "PE") self.assert_select(span, "ALL_ATTRIBUTES") self.assert_consumed_capacity(span, self.default_table_name) @@ -419,7 +419,7 @@ def test_scan(self): Select="ALL_ATTRIBUTES", TotalSegments=17, Segment=21, - ProjectionExpression="1,2", + ProjectionExpression="PE", ConsistentRead=True, ReturnConsumedCapacity="TOTAL", ) @@ -440,7 +440,7 @@ def test_scan(self): self.assert_consistent_read(span, True) self.assert_index_name(span, "lsi") self.assert_limit(span, 42) - self.assert_projection(span, "1,2") + self.assert_projection(span, "PE") self.assert_select(span, "ALL_ATTRIBUTES") self.assert_consumed_capacity(span, self.default_table_name) diff --git a/instrumentation/opentelemetry-instrumentation-pika/tests/test_utils.py b/instrumentation/opentelemetry-instrumentation-pika/tests/test_utils.py index d651ea64c9..7c0aa7a715 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/tests/test_utils.py +++ b/instrumentation/opentelemetry-instrumentation-pika/tests/test_utils.py @@ -558,7 +558,7 @@ def test_decorate_deque_proxy( self.assertEqual(res, evt) generator_info.pending_events.popleft.assert_called_once() extract.assert_not_called() - context_get_current.not_called() + context_get_current.assert_not_called() context_detach.assert_called_once() context_attach.assert_not_called() get_span.assert_not_called() diff --git a/tox.ini b/tox.ini index 0f1e8badcc..d6fb9eee10 100644 --- a/tox.ini +++ b/tox.ini @@ -1198,8 +1198,8 @@ deps = -r dev-requirements.txt commands = - black --config {toxinidir}/pyproject.toml {{toxinidir}} --diff --check - isort --settings-path {toxinidir}/.isort.cfg {{toxinidir}} --diff --check-only + black --config {toxinidir}/pyproject.toml {toxinidir} --diff --check + isort --settings-path {toxinidir}/.isort.cfg {toxinidir} --diff --check-only flake8 --config {toxinidir}/.flake8 {toxinidir} [testenv:spellcheck] From e6409568c11f5ec1341e85770f2f01dded676d7a Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 24 May 2024 20:12:53 +0200 Subject: [PATCH 008/335] Reenable pylint broad exception (#2536) --- .pylintrc | 2 +- .../tests/test_aiopg_integration.py | 11 +++++++---- .../tests/mocks/lambda_function.py | 1 + .../tests/test_dbapi_integration.py | 3 +++ .../tests/test_aio_client_interceptor_hooks.py | 4 ++-- .../tests/test_client_interceptor_hooks.py | 4 ++-- .../tests/test_psycopg_integration.py | 6 +++--- .../tests/test_urllib_integration.py | 2 +- 8 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.pylintrc b/.pylintrc index 114dadef75..9f6c80faa9 100644 --- a/.pylintrc +++ b/.pylintrc @@ -492,4 +492,4 @@ min-public-methods=2 # Exceptions that will emit a warning when being caught. Defaults to # "Exception". -overgeneral-exceptions=Exception +overgeneral-exceptions=builtins.Exception diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py b/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py index fb76bd0f38..c497ae4564 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py @@ -17,6 +17,7 @@ from unittest.mock import MagicMock import aiopg +import psycopg2 import opentelemetry.instrumentation.aiopg from opentelemetry import trace as trace_api @@ -384,7 +385,9 @@ def test_span_failed(self): span.attributes[SpanAttributes.DB_STATEMENT], "Test query" ) self.assertIs(span.status.status_code, trace_api.StatusCode.ERROR) - self.assertEqual(span.status.description, "Exception: Test Exception") + self.assertEqual( + span.status.description, "ProgrammingError: Test Exception" + ) def test_executemany(self): db_integration = AiopgIntegration(self.tracer, "testcomponent") @@ -570,17 +573,17 @@ class MockCursor: # pylint: disable=unused-argument, no-self-use async def execute(self, query, params=None, throw_exception=False): if throw_exception: - raise Exception("Test Exception") + raise psycopg2.ProgrammingError("Test Exception") # pylint: disable=unused-argument, no-self-use async def executemany(self, query, params=None, throw_exception=False): if throw_exception: - raise Exception("Test Exception") + raise psycopg2.ProgrammingError("Test Exception") # pylint: disable=unused-argument, no-self-use async def callproc(self, query, params=None, throw_exception=False): if throw_exception: - raise Exception("Test Exception") + raise psycopg2.ProgrammingError("Test Exception") def close(self): pass diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py index a878d0f06a..539c896a0b 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py @@ -22,4 +22,5 @@ def rest_api_handler(event, context): def handler_exc(event, context): + # pylint: disable=broad-exception-raised raise Exception("500 internal server error") diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index d0835e93e6..eb2d628a3a 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -419,11 +419,13 @@ def __init__(self) -> None: # pylint: disable=unused-argument, no-self-use def execute(self, query, params=None, throw_exception=False): if throw_exception: + # pylint: disable=broad-exception-raised raise Exception("Test Exception") # pylint: disable=unused-argument, no-self-use def executemany(self, query, params=None, throw_exception=False): if throw_exception: + # pylint: disable=broad-exception-raised raise Exception("Test Exception") self.query = query self.params = params @@ -431,4 +433,5 @@ def executemany(self, query, params=None, throw_exception=False): # pylint: disable=unused-argument, no-self-use def callproc(self, query, params=None, throw_exception=False): if throw_exception: + # pylint: disable=broad-exception-raised raise Exception("Test Exception") diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py index fe906b26c1..9086d8b0f7 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py @@ -47,11 +47,11 @@ def response_hook(span, response): def request_hook_with_exception(_span, _request): - raise Exception() + raise Exception() # pylint: disable=broad-exception-raised def response_hook_with_exception(_span, _response): - raise Exception() + raise Exception() # pylint: disable=broad-exception-raised @pytest.mark.asyncio diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_hooks.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_hooks.py index aeecffc71c..ac65c76c34 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_hooks.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_hooks.py @@ -73,11 +73,11 @@ def response_hook(span, response): def request_hook_with_exception(_span, _request): - raise Exception() + raise Exception() # pylint: disable=broad-exception-raised def response_hook_with_exception(_span, _response): - raise Exception() + raise Exception() # pylint: disable=broad-exception-raised class TestHooks(TestBase): diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py index 4fbcac6042..e2b3ed917a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py @@ -53,17 +53,17 @@ def __init__(self, *args, **kwargs): # pylint: disable=unused-argument, no-self-use async def execute(self, query, params=None, throw_exception=False): if throw_exception: - raise Exception("Test Exception") + raise psycopg.Error("Test Exception") # pylint: disable=unused-argument, no-self-use async def executemany(self, query, params=None, throw_exception=False): if throw_exception: - raise Exception("Test Exception") + raise psycopg.Error("Test Exception") # pylint: disable=unused-argument, no-self-use async def callproc(self, query, params=None, throw_exception=False): if throw_exception: - raise Exception("Test Exception") + raise psycopg.Error("Test Exception") async def __aenter__(self, *args, **kwargs): return self diff --git a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py index 36189e12c1..f73f0d1b97 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py @@ -99,7 +99,7 @@ def timeout_exception_callback(*_, **__): @staticmethod def base_exception_callback(*_, **__): - raise Exception("test") + raise Exception("test") # pylint: disable=broad-exception-raised def assert_span(self, exporter=None, num_spans=1): if exporter is None: From 65b4f850a03135bff18a95e62465da881c25f0ec Mon Sep 17 00:00:00 2001 From: Tim Hutchinson Date: Fri, 24 May 2024 15:06:53 -0400 Subject: [PATCH 009/335] Preserve brackets around literal IPv6 hosts (#2552) --- CHANGELOG.md | 1 + .../src/opentelemetry/util/http/__init__.py | 6 +---- .../tests/test_remove_credentials.py | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 util/opentelemetry-util-http/tests/test_remove_credentials.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 038706f35c..3232e6fef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2420](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2420)) - `opentelemetry-instrumentation-asyncio` Check for __name__ attribute in the coroutine ([#2521](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2521)) +- `opentelemetry-util-http` Preserve brackets around literal IPv6 hosts ([#2552](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2552)) ## Version 1.24.0/0.45b0 (2024-03-28) diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index 1f7ce98937..e8a2cf2034 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -166,11 +166,7 @@ def remove_url_credentials(url: str) -> str: parsed = urlparse(url) if all([parsed.scheme, parsed.netloc]): # checks for valid url parsed_url = urlparse(url) - netloc = ( - (":".join(((parsed_url.hostname or ""), str(parsed_url.port)))) - if parsed_url.port - else (parsed_url.hostname or "") - ) + _, _, netloc = parsed.netloc.rpartition("@") return urlunparse( ( parsed_url.scheme, diff --git a/util/opentelemetry-util-http/tests/test_remove_credentials.py b/util/opentelemetry-util-http/tests/test_remove_credentials.py new file mode 100644 index 0000000000..b6243145f5 --- /dev/null +++ b/util/opentelemetry-util-http/tests/test_remove_credentials.py @@ -0,0 +1,27 @@ +import unittest + +from opentelemetry.util.http import remove_url_credentials + + +class TestRemoveUrlCredentials(unittest.TestCase): + def test_remove_no_credentials(self): + url = "http://opentelemetry.io:8080/test/path?query=value" + cleaned_url = remove_url_credentials(url) + self.assertEqual(cleaned_url, url) + + def test_remove_credentials(self): + url = "http://someuser:somepass@opentelemetry.io:8080/test/path?query=value" + cleaned_url = remove_url_credentials(url) + self.assertEqual( + cleaned_url, "http://opentelemetry.io:8080/test/path?query=value" + ) + + def test_remove_credentials_ipv4_literal(self): + url = "http://someuser:somepass@127.0.0.1:8080/test/path?query=value" + cleaned_url = remove_url_credentials(url) + self.assertEqual(cleaned_url, "http://127.0.0.1:8080/test/path?query=value") + + def test_remove_credentials_ipv6_literal(self): + url = "http://someuser:somepass@[::1]:8080/test/path?query=value" + cleaned_url = remove_url_credentials(url) + self.assertEqual(cleaned_url, "http://[::1]:8080/test/path?query=value") From eb8e45695e88510a611d2cc04f14cdf56036968a Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 24 May 2024 22:13:37 +0200 Subject: [PATCH 010/335] elasticsearch: don't produce spans if native elasticsearch support is enabled (#2524) --- CHANGELOG.md | 3 ++ .../instrumentation/elasticsearch/__init__.py | 27 +++++++++++++- .../test-requirements-2.txt | 6 ++-- .../tests/test_elasticsearch.py | 35 +++++++++++++++++-- tox.ini | 2 +- 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3232e6fef8..a75e1537cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,10 +54,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2474](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2474)) - `opentelemetry-instrumentation-elasticsearch` Improved support for version 8 ([#2420](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2420)) +- `opentelemetry-instrumentation-elasticsearch` Disabling instrumentation with native OTel support enabled + ([#2524](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2524)) - `opentelemetry-instrumentation-asyncio` Check for __name__ attribute in the coroutine ([#2521](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2521)) - `opentelemetry-util-http` Preserve brackets around literal IPv6 hosts ([#2552](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2552)) + ## Version 1.24.0/0.45b0 (2024-03-28) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py index acf4596fb0..f8d7920e20 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py @@ -16,6 +16,15 @@ This library allows tracing HTTP elasticsearch made by the `elasticsearch `_ library. +.. warning:: + The elasticsearch package got native OpenTelemetry support since version + `8.13 `_. + To avoid duplicated tracing this instrumentation disables itself if it finds an elasticsearch client + that has OpenTelemetry support enabled. + + Please be aware that the two libraries may use a different semantic convention, see + `elasticsearch documentation `_. + Usage ----- @@ -54,7 +63,7 @@ def response_hook(span: Span, response: dict) for example: -.. code: python +.. code-block: python from opentelemetry.instrumentation.elasticsearch import ElasticsearchInstrumentor import elasticsearch @@ -81,6 +90,7 @@ def response_hook(span, response): """ import re +import warnings from logging import getLogger from os import environ from typing import Collection @@ -197,6 +207,16 @@ def _wrap_perform_request( ): # pylint: disable=R0912,R0914 def wrapper(wrapped, _, args, kwargs): + # if wrapped elasticsearch has native OTel instrumentation just call the wrapped function + otel_span = kwargs.get("otel_span") + if otel_span and otel_span.otel_span: + warnings.warn( + "Instrumentation disabled, relying on elasticsearch native OTel support, see " + "https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/elasticsearch/elasticsearch.html", + Warning, + ) + return wrapped(*args, **kwargs) + method = url = None try: method, url, *_ = args @@ -249,6 +269,11 @@ def normalize_kwargs(k, v): v = str(v) elif isinstance(v, elastic_transport.HttpHeaders): v = dict(v) + elif isinstance( + v, elastic_transport.OpenTelemetrySpan + ): + # the transport Span is always a dummy one + v = None return (k, v) hook_kwargs = dict( diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index 23d87f93dd..6b0d677ec7 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -1,9 +1,9 @@ asgiref==3.7.2 attrs==23.2.0 Deprecated==1.2.14 -elasticsearch==8.12.1 -elasticsearch-dsl==8.12.0 -elastic-transport==8.12.0 +elasticsearch==8.13.1 +elasticsearch-dsl==8.13.1 +elastic-transport==8.13.0 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==23.2 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py index b0ee170329..b7e24d87c9 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py @@ -23,6 +23,7 @@ import elasticsearch.exceptions from elasticsearch import Elasticsearch from elasticsearch_dsl import Search +from pytest import mark import opentelemetry.instrumentation.elasticsearch from opentelemetry import trace @@ -36,7 +37,7 @@ from . import sanitization_queries # pylint: disable=no-name-in-module -major_version = elasticsearch.VERSION[0] +major_version, minor_version = elasticsearch.VERSION[:2] if major_version == 8: from . import helpers_es8 as helpers # pylint: disable=no-name-in-module @@ -70,6 +71,9 @@ def get_elasticsearch_client(*args, **kwargs): @mock.patch(helpers.perform_request_mock_path) +@mock.patch.dict( + os.environ, {"OTEL_PYTHON_INSTRUMENTATION_ELASTICSEARCH_ENABLED": "false"} +) class TestElasticsearchIntegration(TestBase): search_attributes = { SpanAttributes.DB_SYSTEM: "elasticsearch", @@ -110,7 +114,6 @@ def test_instrumentor(self, request_mock): span = spans_list[0] # Check version and name in span's instrumentation info - # self.assertEqualSpanInstrumentationInfo(span, opentelemetry.instrumentation.elasticsearch) self.assertEqualSpanInstrumentationInfo( span, opentelemetry.instrumentation.elasticsearch ) @@ -475,6 +478,7 @@ def request_hook(span, method, url, kwargs): "headers": { "accept": "application/vnd.elasticsearch+json; compatible-with=8" }, + "otel_span": None, } elif major_version == 7: expected_kwargs = { @@ -607,3 +611,30 @@ def test_bulk(self, request_mock): self.assertEqualSpanInstrumentationInfo( span, opentelemetry.instrumentation.elasticsearch ) + + @mark.skipif( + (major_version, minor_version) < (8, 13), + reason="Native OTel since elasticsearch 8.13", + ) + @mock.patch.dict( + os.environ, + {"OTEL_PYTHON_INSTRUMENTATION_ELASTICSEARCH_ENABLED": "true"}, + ) + def test_instrumentation_is_disabled_if_native_support_enabled( + self, request_mock + ): + request_mock.return_value = helpers.mock_response("{}") + + es = get_elasticsearch_client(hosts=["http://localhost:9200"]) + es.index( + index="sw", + id=1, + **normalize_arguments(body={"name": "adam"}, doc_type="_doc"), + ) + + spans_list = self.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + + # Check that name in span's instrumentation info is not from this instrumentation + self.assertEqual(span.instrumentation_info.name, "elasticsearch-api") diff --git a/tox.ini b/tox.ini index d6fb9eee10..a014306640 100644 --- a/tox.ini +++ b/tox.ini @@ -92,7 +92,7 @@ envlist = ; below mean these dependencies are being used: ; 0: elasticsearch-dsl==6.4.0 elasticsearch==6.8.2 ; 1: elasticsearch-dsl==7.4.1 elasticsearch==7.17.9 - ; 2: elasticsearch-dsl>=8.0,<8.13 elasticsearch>=8.0,<8.13 + ; 2: elasticsearch-dsl==8.13.1 elasticsearch==8.13.1 py3{8,9,10,11}-test-instrumentation-elasticsearch-{0,1,2} pypy3-test-instrumentation-elasticsearch-{0,1,2} lint-instrumentation-elasticsearch From 88111d0a8381bdc440c660b7e802dc951607392a Mon Sep 17 00:00:00 2001 From: Martin Stolle <121817095+stollero@users.noreply.github.com> Date: Tue, 28 May 2024 20:34:28 +0200 Subject: [PATCH 011/335] fix(requests): Fix wrong time unit for duration histogram (#2553) --- CHANGELOG.md | 3 ++- .../src/opentelemetry/instrumentation/requests/__init__.py | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a75e1537cc..7ba8e6d3e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,9 +58,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2524](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2524)) - `opentelemetry-instrumentation-asyncio` Check for __name__ attribute in the coroutine ([#2521](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2521)) +- `opentelemetry-instrumentation-requests` Fix wrong time unit for duration histogram + ([#2553](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2553)) - `opentelemetry-util-http` Preserve brackets around literal IPv6 hosts ([#2552](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2552)) - ## Version 1.24.0/0.45b0 (2024-03-28) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 12797d6f5e..8c54482a46 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -229,9 +229,7 @@ def get_or_create_headers(): exception = exc result = getattr(exc, "response", None) finally: - elapsed_time = max( - round((default_timer() - start_time) * 1000), 0 - ) + elapsed_time = max(default_timer() - start_time, 0) if isinstance(result, Response): span_attributes = {} From 59a737c285f7e3b0e3901781d805f6ecdad41e45 Mon Sep 17 00:00:00 2001 From: Mike Goldsmith Date: Tue, 28 May 2024 19:49:00 +0100 Subject: [PATCH 012/335] Add key predicate to baggage span processor (#2535) * Add key predicate to baggage span processor * add changelog entry * fix linting * more linter fixes --------- Co-authored-by: Diego Hurtado --- CHANGELOG.md | 2 + .../README.rst | 29 +++++++ .../processor/baggage/__init__.py | 4 +- .../processor/baggage/processor.py | 15 +++- .../tests/test_baggage_processor.py | 86 ++++++++++++++++++- 5 files changed, 126 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ba8e6d3e2..6876e2cf9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2397](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2397))) - `opentelemetry-processor-baggage` Initial release ([#2436](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2436)) +- `opentelemetry-processor-baggage` Add baggage key predicate + ([#2535](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2535)) ### Fixed diff --git a/processor/opentelemetry-processor-baggage/README.rst b/processor/opentelemetry-processor-baggage/README.rst index 2768758a99..a111166cef 100644 --- a/processor/opentelemetry-processor-baggage/README.rst +++ b/processor/opentelemetry-processor-baggage/README.rst @@ -20,3 +20,32 @@ Do not put sensitive information in Baggage. To repeat: a consequence of adding data to Baggage is that the keys and values will appear in all outgoing HTTP headers from the application. + +## Usage + +Add the span processor when configuring the tracer provider. + +To configure the span processor to copy all baggage entries during configuration: + +```python +from opentelemetry.processor.baggage import BaggageSpanProcessor, ALLOW_ALL_BAGGAGE_KEYS + +tracer_provider = TracerProvider() +tracer_provider.add_span_processor(BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS)) +``` + +Alternatively, you can provide a custom baggage key predicate to select which baggage keys you want to copy. + +For example, to only copy baggage entries that start with `my-key`: + +```python +starts_with_predicate = lambda baggage_key: baggage_key.startswith("my-key") +tracer_provider.add_span_processor(BaggageSpanProcessor(starts_with_predicate)) +``` + +For example, to only copy baggage entries that match the regex `^key.+`: + +```python +regex_predicate = lambda baggage_key: baggage_key.startswith("^key.+") +tracer_provider.add_span_processor(BaggageSpanProcessor(regex_predicate)) +``` \ No newline at end of file diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/__init__.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/__init__.py index a740c66491..fcff749d64 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/__init__.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/__init__.py @@ -14,7 +14,7 @@ # pylint: disable=import-error -from .processor import BaggageSpanProcessor +from .processor import ALLOW_ALL_BAGGAGE_KEYS, BaggageSpanProcessor from .version import __version__ -__all__ = ["BaggageSpanProcessor", "__version__"] +__all__ = ["ALLOW_ALL_BAGGAGE_KEYS", "BaggageSpanProcessor", "__version__"] diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py index 36df06a94c..d14cf3a7e6 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py @@ -12,13 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Optional +from typing import Callable, Optional from opentelemetry.baggage import get_all as get_all_baggage from opentelemetry.context import Context from opentelemetry.sdk.trace.export import SpanProcessor from opentelemetry.trace import Span +# A BaggageKeyPredicate is a function that takes a baggage key and returns a boolean +BaggageKeyPredicateT = Callable[[str], bool] + +# A BaggageKeyPredicate that always returns True, allowing all baggage keys to be added to spans +ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True + class BaggageSpanProcessor(SpanProcessor): """ @@ -44,12 +50,13 @@ class BaggageSpanProcessor(SpanProcessor): """ - def __init__(self) -> None: - pass + def __init__(self, baggage_key_predicate: BaggageKeyPredicateT) -> None: + self._baggage_key_predicate = baggage_key_predicate def on_start( self, span: "Span", parent_context: Optional[Context] = None ) -> None: baggage = get_all_baggage(parent_context) for key, value in baggage.items(): - span.set_attribute(key, value) + if self._baggage_key_predicate(key): + span.set_attribute(key, value) diff --git a/processor/opentelemetry-processor-baggage/tests/test_baggage_processor.py b/processor/opentelemetry-processor-baggage/tests/test_baggage_processor.py index 63a71c3cba..fb89ef5eb1 100644 --- a/processor/opentelemetry-processor-baggage/tests/test_baggage_processor.py +++ b/processor/opentelemetry-processor-baggage/tests/test_baggage_processor.py @@ -12,12 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import re import unittest from opentelemetry.baggage import get_all as get_all_baggage from opentelemetry.baggage import set_baggage from opentelemetry.context import attach, detach -from opentelemetry.processor.baggage import BaggageSpanProcessor +from opentelemetry.processor.baggage import ( + ALLOW_ALL_BAGGAGE_KEYS, + BaggageSpanProcessor, +) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SpanProcessor from opentelemetry.trace import Span, Tracer @@ -25,13 +29,77 @@ class BaggageSpanProcessorTest(unittest.TestCase): def test_check_the_baggage(self): - self.assertIsInstance(BaggageSpanProcessor(), SpanProcessor) + self.assertIsInstance( + BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS), SpanProcessor + ) def test_set_baggage_attaches_to_child_spans_and_detaches_properly_with_context( self, ): tracer_provider = TracerProvider() - tracer_provider.add_span_processor(BaggageSpanProcessor()) + tracer_provider.add_span_processor( + BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS) + ) + + # tracer has no baggage to start + tracer = tracer_provider.get_tracer("my-tracer") + self.assertIsInstance(tracer, Tracer) + self.assertEqual(get_all_baggage(), {}) + # set baggage in context + ctx = set_baggage("queen", "bee") + with tracer.start_as_current_span( + name="bumble", context=ctx + ) as bumble_span: + # span should have baggage key-value pair in context + self.assertEqual(get_all_baggage(ctx), {"queen": "bee"}) + # span should have baggage key-value pair in attribute + self.assertEqual(bumble_span._attributes["queen"], "bee") + with tracer.start_as_current_span( + name="child_span", context=ctx + ) as child_span: + self.assertIsInstance(child_span, Span) + # child span should have baggage key-value pair in context + self.assertEqual(get_all_baggage(ctx), {"queen": "bee"}) + # child span should have baggage key-value pair in attribute + self.assertEqual(child_span._attributes["queen"], "bee") + + def test_baggage_span_processor_with_string_prefix( + self, + ): + tracer_provider = TracerProvider() + tracer_provider.add_span_processor( + BaggageSpanProcessor(self.has_prefix) + ) + + # tracer has no baggage to start + tracer = tracer_provider.get_tracer("my-tracer") + self.assertIsInstance(tracer, Tracer) + self.assertEqual(get_all_baggage(), {}) + # set baggage in context + ctx = set_baggage("queen", "bee") + with tracer.start_as_current_span( + name="bumble", context=ctx + ) as bumble_span: + # span should have baggage key-value pair in context + self.assertEqual(get_all_baggage(ctx), {"queen": "bee"}) + # span should have baggage key-value pair in attribute + self.assertEqual(bumble_span._attributes["queen"], "bee") + with tracer.start_as_current_span( + name="child_span", context=ctx + ) as child_span: + self.assertIsInstance(child_span, Span) + # child span should have baggage key-value pair in context + self.assertEqual(get_all_baggage(ctx), {"queen": "bee"}) + # child span should have baggage key-value pair in attribute + self.assertEqual(child_span._attributes["queen"], "bee") + + def test_baggage_span_processor_with_regex( + self, + ): + tracer_provider = TracerProvider() + tracer_provider.add_span_processor( + BaggageSpanProcessor(self.matches_regex) + ) # tracer has no baggage to start tracer = tracer_provider.get_tracer("my-tracer") @@ -59,7 +127,9 @@ def test_set_baggage_attaches_to_child_spans_and_detaches_properly_with_token( self, ): tracer_provider = TracerProvider() - tracer_provider.add_span_processor(BaggageSpanProcessor()) + tracer_provider.add_span_processor( + BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS) + ) # tracer has no baggage to start tracer = tracer_provider.get_tracer("my-tracer") @@ -87,3 +157,11 @@ def test_set_baggage_attaches_to_child_spans_and_detaches_properly_with_token( detach(moar_token) detach(honey_token) self.assertEqual(get_all_baggage(), {}) + + @staticmethod + def has_prefix(baggage_key: str) -> bool: + return baggage_key.startswith("que") + + @staticmethod + def matches_regex(baggage_key: str) -> bool: + return re.match(r"que.*", baggage_key) is not None From ac97b004571474f22e06a46b0e056e48900b607e Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 28 May 2024 23:31:44 +0200 Subject: [PATCH 013/335] Fix typos in test names (#2558) --- .../tests/test_fastapi_instrumentation.py | 2 +- .../tests/test_automatic.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 4269dfa2e4..f9261ad5db 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -279,7 +279,7 @@ def test_basic_post_request_metric_success(self): if isinstance(point, NumberDataPoint): self.assertEqual(point.value, 0) - def test_metric_uninstruemnt_app(self): + def test_metric_uninstrument_app(self): self._client.get("/foobar") self._instrumentor.uninstrument_app(self._app) self._client.get("/foobar") diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py index 4715e0b461..7b48e16e17 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py @@ -245,7 +245,7 @@ def test_basic_metric_success(self): ) self.assertEqual(point.value, 0) - def test_metric_uninstruemnt(self): + def test_metric_uninstrument(self): self.client.get("/hello/756") PyramidInstrumentor().uninstrument() self.config = Configurator() From f7cef147390fd39070630ac3730f3a6475a05e34 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 28 May 2024 23:56:38 +0200 Subject: [PATCH 014/335] distro: decouple default configuration test from environment (#2561) --- opentelemetry-distro/tests/test_distro.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/opentelemetry-distro/tests/test_distro.py b/opentelemetry-distro/tests/test_distro.py index dd8f9c4cc4..ea7b9f08c8 100644 --- a/opentelemetry-distro/tests/test_distro.py +++ b/opentelemetry-distro/tests/test_distro.py @@ -14,7 +14,7 @@ # type: ignore import os -from unittest import TestCase +from unittest import TestCase, mock from pkg_resources import DistributionNotFound, require @@ -33,17 +33,10 @@ def test_package_available(self): except DistributionNotFound: self.fail("opentelemetry-distro not installed") + @mock.patch.dict("os.environ", {}, clear=True) def test_default_configuration(self): distro = OpenTelemetryDistro() - self.assertIsNone(os.environ.get(OTEL_TRACES_EXPORTER)) - self.assertIsNone(os.environ.get(OTEL_METRICS_EXPORTER)) distro.configure() - self.assertEqual( - "otlp", os.environ.get(OTEL_TRACES_EXPORTER) - ) - self.assertEqual( - "otlp", os.environ.get(OTEL_METRICS_EXPORTER) - ) - self.assertEqual( - "grpc", os.environ.get(OTEL_EXPORTER_OTLP_PROTOCOL) - ) + self.assertEqual("otlp", os.environ.get(OTEL_TRACES_EXPORTER)) + self.assertEqual("otlp", os.environ.get(OTEL_METRICS_EXPORTER)) + self.assertEqual("grpc", os.environ.get(OTEL_EXPORTER_OTLP_PROTOCOL)) From 25e429aaf98e0eb43ab907b61940cea9c2b86717 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 29 May 2024 01:18:09 +0200 Subject: [PATCH 015/335] instrumentation: revise BaseDistro.load_instrumentor documentation (#2530) --- .../src/opentelemetry/instrumentation/distro.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py index cc1c99c1e0..93646bbb2f 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py @@ -50,9 +50,10 @@ def configure(self, **kwargs): def load_instrumentor( # pylint: disable=no-self-use self, entry_point: EntryPoint, **kwargs ): - """Takes a collection of instrumentation entry points - and activates them by instantiating and calling instrument() - on each one. + """Takes an instrumentation entry point and activates it by instantiating + and calling instrument() on it. + This is called for each opentelemetry_instrumentor entry point by auto + instrumentation. Distros can override this method to customize the behavior by inspecting each entry point and configuring them in special ways, From bd9156fff84e4d30592d118aa8ee9e3d5d5499f9 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 29 May 2024 17:56:27 +0200 Subject: [PATCH 016/335] Remove unrelated packages from test requirements (#2559) * botocore: remove random packages from test-requirements Refs #1736 * boto: remove random packages from test requirements Refs #1736 * tox: re-enable boto3sqs tests with pypy3 * threading: remove confluent-kafka from test requirements --- .../test-requirements.txt | 34 ++----------------- .../test-requirements.txt | 30 +--------------- .../test-requirements.txt | 1 - tox.ini | 3 +- 4 files changed, 4 insertions(+), 64 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 92c356ebe1..4f8c5d2b67 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -1,69 +1,39 @@ -annotated-types==0.6.0 asgiref==3.7.2 attrs==23.2.0 -aws-sam-translator==1.85.0 -aws-xray-sdk==2.12.1 boto==2.49.0 boto3==1.34.44 botocore==1.34.44 certifi==2024.2.2 cffi==1.16.0 -cfn-lint==0.85.2 charset-normalizer==3.3.2 cryptography==42.0.3 Deprecated==1.2.14 docker==7.0.0 -ecdsa==0.18.0 -graphql-core==3.2.3 idna==3.6 importlib-metadata==6.11.0 -importlib-resources==6.1.1 iniconfig==2.0.0 -Jinja2==3.1.3 +Jinja2==3.1.4 jmespath==1.0.1 -jschema-to-python==1.2.3 -jsondiff==2.0.0 -jsonpatch==1.33 -jsonpickle==3.0.2 -jsonpointer==2.4 -jsonschema==4.21.1 -jsonschema-specifications==2023.12.1 -junit-xml==1.9 MarkupSafe==2.1.5 moto==2.3.2 -mpmath==1.3.0 -networkx==3.1 packaging==23.2 -pbr==6.0.0 -pkgutil_resolve_name==1.3.10 pluggy==1.4.0 py==1.11.0 py-cpuinfo==9.0.0 -pyasn1==0.5.1 pycparser==2.21 -pydantic==2.6.1 -pydantic_core==2.16.2 pytest==7.1.3 pytest-benchmark==4.0.0 python-dateutil==2.8.2 -python-jose==3.3.0 pytz==2024.1 PyYAML==6.0.1 -referencing==0.33.0 -regex==2023.12.25 requests==2.31.0 responses==0.25.0 -rpds-py==0.18.0 -rsa==4.9 s3transfer==0.10.0 -sarif-om==1.0.4 six==1.16.0 -sshpubkeys==3.3.1 -sympy==1.12 tomli==2.0.1 typing_extensions==4.9.0 urllib3==1.26.18 -Werkzeug==3.0.1 +Werkzeug==2.1.2 wrapt==1.16.0 xmltodict==0.13.0 zipp==3.17.0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index 7c11b1e063..7229f0f721 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -1,63 +1,35 @@ -annotated-types==0.6.0 asgiref==3.7.2 attrs==23.2.0 -aws-sam-translator==1.85.0 aws-xray-sdk==2.12.1 boto3==1.28.80 botocore==1.31.80 certifi==2024.2.2 cffi==1.16.0 -cfn-lint==0.85.2 charset-normalizer==3.3.2 cryptography==42.0.5 Deprecated==1.2.14 docker==7.0.0 -ecdsa==0.18.0 idna==3.6 importlib-metadata==6.11.0 -importlib-resources==6.1.1 iniconfig==2.0.0 -Jinja2==3.1.3 +Jinja2==3.1.4 jmespath==1.0.1 -jschema-to-python==1.2.3 -jsondiff==2.0.0 -jsonpatch==1.33 -jsonpickle==3.0.3 -jsonpointer==2.4 -jsonschema==4.21.1 -jsonschema-specifications==2023.12.1 -junit-xml==1.9 MarkupSafe==2.0.1 moto==3.1.19 -mpmath==1.3.0 -networkx==3.1 packaging==23.2 -pbr==6.0.0 -pkgutil_resolve_name==1.3.10 pluggy==1.4.0 py==1.11.0 py-cpuinfo==9.0.0 -pyasn1==0.5.1 pycparser==2.21 -pydantic==2.6.2 -pydantic_core==2.16.3 pytest==7.1.3 pytest-benchmark==4.0.0 python-dateutil==2.8.2 -python-jose==3.3.0 pytz==2024.1 PyYAML==6.0.1 -referencing==0.33.0 -regex==2023.12.25 requests==2.31.0 responses==0.25.0 -rpds-py==0.18.0 -rsa==4.9 s3transfer==0.7.0 -sarif-om==1.0.4 six==1.16.0 -sshpubkeys==3.3.1 -sympy==1.12 tomli==2.0.1 typing_extensions==4.9.0 urllib3==1.26.18 diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index ffda21f234..4f9b027918 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.7.2 attrs==23.2.0 -confluent-kafka==2.3.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/tox.ini b/tox.ini index a014306640..e97476a850 100644 --- a/tox.ini +++ b/tox.ini @@ -54,8 +54,7 @@ envlist = ; opentelemetry-instrumentation-boto3sqs py3{8,9,10,11}-test-instrumentation-boto3sqs - ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 - ; pypy3-test-instrumentation-boto3sqs + pypy3-test-instrumentation-boto3sqs lint-instrumentation-boto3sqs ; opentelemetry-instrumentation-django From 7bddbb54195be4004275c83ef2592b362e443dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 29 May 2024 14:17:50 -0300 Subject: [PATCH 017/335] fix: remove dependency on sdk for system-metrics instrumentation (#2557) --- .../pyproject.toml | 1 - .../opentelemetry/instrumentation/system_metrics/__init__.py | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index fe60ca1251..aa2d8083ec 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -26,7 +26,6 @@ classifiers = [ dependencies = [ "opentelemetry-instrumentation == 0.46b0.dev", "opentelemetry-api ~= 1.11", - "opentelemetry-sdk ~= 1.11", "psutil ~= 5.9", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index 74d4f6a431..6342d287d5 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -91,7 +91,6 @@ from opentelemetry.instrumentation.system_metrics.package import _instruments from opentelemetry.instrumentation.system_metrics.version import __version__ from opentelemetry.metrics import CallbackOptions, Observation, get_meter -from opentelemetry.sdk.util import get_dict_as_key _logger = logging.getLogger(__name__) @@ -638,8 +637,8 @@ def _get_system_network_connections( net_connection, metric ) - connection_counters_key = get_dict_as_key( - self._system_network_connections_labels + connection_counters_key = tuple( + sorted(self._system_network_connections_labels.items()) ) if connection_counters_key in connection_counters: From 41792e7bb322455705088b18c3a4e1e530fe01c7 Mon Sep 17 00:00:00 2001 From: dferrochio Date: Thu, 30 May 2024 18:27:35 -0300 Subject: [PATCH 018/335] Add confluent kafka producer poll and flush returns (#2527) --- CHANGELOG.md | 1 + .../confluent_kafka/__init__.py | 4 +- .../tests/test_instrumentation.py | 34 ++++++++++++- .../tests/utils.py | 48 ++++++++++++++++++- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6876e2cf9e..c9cafd2dc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking changes +- Add return statement to Confluent kafka Producer poll() and flush() calls when instrumented by ConfluentKafkaInstrumentor().instrument_producer() ([#2527](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2527)) - Rename `type` attribute to `asgi.event.type` in `opentelemetry-instrumentation-asgi` ([#2300](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2300)) - Rename AwsLambdaInstrumentor span attributes `faas.id` to `cloud.resource_id`, `faas.execution` to `faas.invocation_id` diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index c869d03dd9..30181d39c2 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -151,10 +151,10 @@ def __init__(self, producer: Producer, tracer: Tracer): self._tracer = tracer def flush(self, timeout=-1): - self._producer.flush(timeout) + return self._producer.flush(timeout) def poll(self, timeout=-1): - self._producer.poll(timeout) + return self._producer.poll(timeout) def produce( self, topic, value=None, *args, **kwargs diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py index 21d5bd6f83..205de27733 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py @@ -31,7 +31,7 @@ ) from opentelemetry.test.test_base import TestBase -from .utils import MockConsumer, MockedMessage +from .utils import MockConsumer, MockedMessage, MockedProducer class TestConfluentKafka(TestBase): @@ -246,3 +246,35 @@ def _compare_spans(self, spans, expected_spans): self.assertEqual( expected_attribute_value, span.attributes[attribute_key] ) + + def test_producer_poll(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + message_queue = [] + + producer = MockedProducer( + message_queue, + { + "bootstrap.servers": "localhost:29092", + }, + ) + + producer = instrumentation.instrument_producer(producer) + producer.produce(topic="topic-1", key="key-1", value="value-1") + msg = producer.poll() + self.assertIsNotNone(msg) + + def test_producer_flush(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + message_queue = [] + + producer = MockedProducer( + message_queue, + { + "bootstrap.servers": "localhost:29092", + }, + ) + + producer = instrumentation.instrument_producer(producer) + producer.produce(topic="topic-1", key="key-1", value="value-1") + msg = producer.flush() + self.assertIsNotNone(msg) diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py index 798daaeff4..92e11798f6 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py @@ -1,4 +1,6 @@ -from confluent_kafka import Consumer +from typing import Optional + +from confluent_kafka import Consumer, Producer class MockConsumer(Consumer): @@ -20,11 +22,21 @@ def poll(self, timeout=None): class MockedMessage: - def __init__(self, topic: str, partition: int, offset: int, headers): + def __init__( + self, + topic: str, + partition: int, + offset: int, + headers, + key: Optional[str] = None, + value: Optional[str] = None, + ): self._topic = topic self._partition = partition self._offset = offset self._headers = headers + self._key = key + self._value = value def topic(self): return self._topic @@ -37,3 +49,35 @@ def offset(self): def headers(self): return self._headers + + def key(self): + return self._key + + def value(self): + return self._value + + +class MockedProducer(Producer): + def __init__(self, queue, config): + self._queue = queue + super().__init__(config) + + def produce( + self, *args, **kwargs + ): # pylint: disable=keyword-arg-before-vararg + self._queue.append( + MockedMessage( + topic=kwargs.get("topic"), + partition=0, + offset=0, + headers=[], + key=kwargs.get("key"), + value=kwargs.get("value"), + ) + ) + + def poll(self, *args, **kwargs): + return len(self._queue) + + def flush(self, *args, **kwargs): + return len(self._queue) From 728976fb10e595a445e0a87be26717d5c069c9a8 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Fri, 31 May 2024 00:50:53 +0300 Subject: [PATCH 019/335] Fix net peer attribute for unix socket connection (#2493) --- CHANGELOG.md | 1 + .../instrumentation/redis/util.py | 12 +-- .../tests/test_redis.py | 85 +++++++++++++++++++ 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9cafd2dc1..17152f3fa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-requests` Fix wrong time unit for duration histogram ([#2553](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2553)) - `opentelemetry-util-http` Preserve brackets around literal IPv6 hosts ([#2552](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2552)) +- `opentelemetry-util-redis` Fix net peer attribute for unix socket connection ([#2493](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2493)) ## Version 1.24.0/0.45b0 (2024-03-28) diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py index 2a24ead79a..4703bc271f 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py @@ -29,7 +29,12 @@ def _extract_conn_attributes(conn_kwargs): } db = conn_kwargs.get("db", 0) attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX] = db - try: + if "path" in conn_kwargs: + attributes[SpanAttributes.NET_PEER_NAME] = conn_kwargs.get("path", "") + attributes[SpanAttributes.NET_TRANSPORT] = ( + NetTransportValues.OTHER.value + ) + else: attributes[SpanAttributes.NET_PEER_NAME] = conn_kwargs.get( "host", "localhost" ) @@ -39,11 +44,6 @@ def _extract_conn_attributes(conn_kwargs): attributes[SpanAttributes.NET_TRANSPORT] = ( NetTransportValues.IP_TCP.value ) - except KeyError: - attributes[SpanAttributes.NET_PEER_NAME] = conn_kwargs.get("path", "") - attributes[SpanAttributes.NET_TRANSPORT] = ( - NetTransportValues.OTHER.value - ) return attributes diff --git a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py index 2d2670fee3..4a2fce5026 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py +++ b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py @@ -20,6 +20,11 @@ from opentelemetry import trace from opentelemetry.instrumentation.redis import RedisInstrumentor +from opentelemetry.semconv.trace import ( + DbSystemValues, + NetTransportValues, + SpanAttributes, +) from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind @@ -226,3 +231,83 @@ def test_no_op_tracer_provider(self): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) + + def test_attributes_default(self): + redis_client = redis.Redis() + + with mock.patch.object(redis_client, "connection"): + redis_client.set("key", "value") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_SYSTEM], + DbSystemValues.REDIS.value, + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX], 0 + ) + self.assertEqual( + span.attributes[SpanAttributes.NET_PEER_NAME], "localhost" + ) + self.assertEqual(span.attributes[SpanAttributes.NET_PEER_PORT], 6379) + self.assertEqual( + span.attributes[SpanAttributes.NET_TRANSPORT], + NetTransportValues.IP_TCP.value, + ) + + def test_attributes_tcp(self): + redis_client = redis.Redis.from_url("redis://foo:bar@1.1.1.1:6380/1") + + with mock.patch.object(redis_client, "connection"): + redis_client.set("key", "value") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_SYSTEM], + DbSystemValues.REDIS.value, + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX], 1 + ) + self.assertEqual( + span.attributes[SpanAttributes.NET_PEER_NAME], "1.1.1.1" + ) + self.assertEqual(span.attributes[SpanAttributes.NET_PEER_PORT], 6380) + self.assertEqual( + span.attributes[SpanAttributes.NET_TRANSPORT], + NetTransportValues.IP_TCP.value, + ) + + def test_attributes_unix_socket(self): + redis_client = redis.Redis.from_url( + "unix://foo@/path/to/socket.sock?db=3&password=bar" + ) + + with mock.patch.object(redis_client, "connection"): + redis_client.set("key", "value") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_SYSTEM], + DbSystemValues.REDIS.value, + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX], 3 + ) + self.assertEqual( + span.attributes[SpanAttributes.NET_PEER_NAME], + "/path/to/socket.sock", + ) + self.assertEqual( + span.attributes[SpanAttributes.NET_TRANSPORT], + NetTransportValues.OTHER.value, + ) From dc711e870ec086c1e598c9f9b6191b8a7eeba42e Mon Sep 17 00:00:00 2001 From: Rytis Bagdziunas Date: Fri, 31 May 2024 00:48:22 +0200 Subject: [PATCH 020/335] Ensure httpx non-client methods are instrumented (#2538) * Ensure httpx non-client methods are instrumented * Update changelog * Added subTest to distinguish tests inside a loop * Updated changelog * Add a comment explaining private attribute usage --------- Co-authored-by: Diego Hurtado --- CHANGELOG.md | 5 +++- .../instrumentation/httpx/__init__.py | 6 +++-- .../tests/test_httpx_integration.py | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17152f3fa7..72ff7ac52c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version (#2500)[https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500] +- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version + ([#2500](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500)) +- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented + ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) - `opentelemetry-instrumentation-grpc` AioClientInterceptor should propagate with a Metadata object ([#2363](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2363)) - `opentelemetry-instrumentation-boto3sqs` Instrument Session and resource diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 7fcc7128be..850e76eea3 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -564,11 +564,13 @@ def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider") _InstrumentedClient._tracer_provider = tracer_provider _InstrumentedAsyncClient._tracer_provider = tracer_provider - httpx.Client = _InstrumentedClient + # Intentionally using a private attribute here, see: + # https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538#discussion_r1610603719 + httpx.Client = httpx._api.Client = _InstrumentedClient httpx.AsyncClient = _InstrumentedAsyncClient def _uninstrument(self, **kwargs): - httpx.Client = self._original_client + httpx.Client = httpx._api.Client = self._original_client httpx.AsyncClient = self._original_async_client _InstrumentedClient._tracer_provider = None _InstrumentedClient._request_hook = None diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index c3f668cafe..d64db1a8f5 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -532,12 +532,36 @@ def test_instrument_client(self): self.assertEqual(result.text, "Hello!") self.assert_span(num_spans=1) + def test_instrumentation_without_client(self): + + HTTPXClientInstrumentor().instrument() + results = [ + httpx.get(self.URL), + httpx.request("GET", self.URL), + ] + with httpx.stream("GET", self.URL) as stream: + stream.read() + results.append(stream) + + spans = self.assert_span(num_spans=len(results)) + for idx, res in enumerate(results): + with self.subTest(idx=idx, res=res): + self.assertEqual(res.text, "Hello!") + self.assertEqual( + spans[idx].attributes[SpanAttributes.HTTP_URL], + self.URL, + ) + + HTTPXClientInstrumentor().uninstrument() + def test_uninstrument(self): HTTPXClientInstrumentor().instrument() HTTPXClientInstrumentor().uninstrument() client = self.create_client() result = self.perform_request(self.URL, client=client) + result_no_client = httpx.get(self.URL) self.assertEqual(result.text, "Hello!") + self.assertEqual(result_no_client.text, "Hello!") self.assert_span(num_spans=0) def test_uninstrument_client(self): From 0db9dbe3113d61c037d773b8f55fc75f4a846992 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 31 May 2024 03:48:51 +0200 Subject: [PATCH 021/335] Update version to 1.26.0.dev/0.47b0.dev (#2568) --- .github/workflows/instrumentations_0.yml | 2 +- .github/workflows/instrumentations_1.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- CHANGELOG.md | 13 ++- _template/version.py | 2 +- eachdist.ini | 4 +- .../prometheus_remote_write/version.py | 2 +- .../pyproject.toml | 2 +- .../exporter/richconsole/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/aio_pika/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_client/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_server/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiopg/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asgi/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asyncio/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncpg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aws_lambda/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto3sqs/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/botocore/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/cassandra/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/celery/version.py | 2 +- .../pyproject.toml | 2 +- .../confluent_kafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/dbapi/version.py | 2 +- .../pyproject.toml | 10 +- .../instrumentation/django/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/elasticsearch/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/falcon/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/fastapi/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/flask/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/grpc/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/httpx/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/jinja2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/kafka/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/logging/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysqlclient/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymemcache/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymongo/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymysql/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/pyramid/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/redis/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/remoulade/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/requests/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/sklearn/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlalchemy/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlite3/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/starlette/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/system_metrics/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/threading/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/tornado/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/tortoiseorm/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib3/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/wsgi/version.py | 2 +- .../pyproject.toml | 96 ++++++++--------- .../contrib-instrumentations/version.py | 2 +- opentelemetry-distro/pyproject.toml | 4 +- .../src/opentelemetry/distro/version.py | 2 +- .../instrumentation/bootstrap_gen.py | 100 +++++++++--------- .../opentelemetry/instrumentation/version.py | 2 +- .../processor/baggage/version.py | 2 +- .../propagators/ot_trace/version.py | 2 +- .../resource/detector/container/version.py | 2 +- .../src/opentelemetry/util/http/version.py | 2 +- 116 files changed, 285 insertions(+), 280 deletions(-) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index a138621633..5fb21ad672 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 955c92e91b5cd4bcfb43c39efcef086b040471d2 + CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e jobs: instrumentations-0: diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 904f2ee999..2bab23d7d2 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 955c92e91b5cd4bcfb43c39efcef086b040471d2 + CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e jobs: instrumentations-1: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 39afb3ee96..859b567824 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 955c92e91b5cd4bcfb43c39efcef086b040471d2 + CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e jobs: lint-3_11: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a129c6e7ce..ee66efac64 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 47d5ad7aae5aef31238ca66e55dc550b307c7b35 + CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e jobs: misc: diff --git a/CHANGELOG.md b/CHANGELOG.md index 72ff7ac52c..778f16c54b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version + ([#2500](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500)) +- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented + ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) + +## Version 1.25.0/0.46b0 (2024-05-30) + ### Breaking changes - Add return statement to Confluent kafka Producer poll() and flush() calls when instrumented by ConfluentKafkaInstrumentor().instrument_producer() ([#2527](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2527)) @@ -42,10 +51,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version - ([#2500](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500)) -- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented - ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) - `opentelemetry-instrumentation-grpc` AioClientInterceptor should propagate with a Metadata object ([#2363](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2363)) - `opentelemetry-instrumentation-boto3sqs` Instrument Session and resource diff --git a/_template/version.py b/_template/version.py index ff4933b20b..b6955b0eca 100644 --- a/_template/version.py +++ b/_template/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/eachdist.ini b/eachdist.ini index 60f1154a83..7f170e4947 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -16,7 +16,7 @@ sortfirst= ext/* [stable] -version=1.25.0.dev +version=1.26.0.dev packages= opentelemetry-sdk @@ -34,7 +34,7 @@ packages= opentelemetry-api [prerelease] -version=0.46b0.dev +version=0.47b0.dev packages= all diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py index ff4933b20b..b6955b0eca 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 9fb32c772c..aa672ac84d 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-sdk ~= 1.12", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "rich>=10.0.0", ] diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py index ff4933b20b..b6955b0eca 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 73c10fffce..71956d28ce 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index 17b92b2cf8..4eb0b25b17 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py index 604195c10e..deef26c62f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index f85cfd6e39..a335800216 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 4a01639d37..17d4513dc9 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index a4072bac7d..3e7fc8b9c9 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ dependencies = [ "asgiref ~= 3.0", "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index 540da184be..b6b272a57a 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.14", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-test-utils == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-test-utils == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 6cdd2e7294..9f4f9edd8a 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index 3088c47dbe..8e559db99b 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -21,9 +21,9 @@ classifiers = [ "Programming Language :: Python :: 3.8", ] dependencies = [ - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "opentelemetry-propagator-aws-xray == 1.0.1", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index 87a323f996..8ddd1f3884 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 2da67c9848..295204abb8 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 7b0b34d255..7749163b51 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "opentelemetry-propagator-aws-xray == 1.0.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 85f187922e..7c55c88b8f 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 7b0027425f..e4b734c0f7 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 9baeaeb40e..13e7ca94cd 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -21,7 +21,7 @@ classifiers = [ "Programming Language :: Python :: 3.8", ] dependencies = [ - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "opentelemetry-api ~= 1.12", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index e726768535..cf8b2d5dd2 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py index 17627b21dc..db4e3a0022 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index c8869d7b29..74a9b10a59 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -25,15 +25,15 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-wsgi == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-wsgi == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] asgi = [ - "opentelemetry-instrumentation-asgi == 0.46b0.dev", + "opentelemetry-instrumentation-asgi == 0.47b0.dev", ] instruments = [ "django >= 1.10", diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index f5ba221b7f..b16f79f2ca 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 93787a010d..14e92041fa 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-wsgi == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-wsgi == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", "packaging >= 20.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 0e11179de2..c8cff0d46d 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-asgi == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-asgi == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 2bc1335a51..f0abd0dc04 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-wsgi == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-wsgi == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", "packaging >= 21.0", "importlib-metadata >= 4.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index 7deffb71e7..6acda1ff8b 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index e4e5575d96..8e94e70de8 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index 6284496ebd..a93fe78d7e 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index 580c076a82..bd06b90f06 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 57572ce634..df254c9d60 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py index 17627b21dc..db4e3a0022 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 481748c007..1c66bb932c 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index c9db02e22f..bb4f62975a 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index a41b7297a8..011bee252c 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", "wrapt >= 1.0.0, < 2.0.0", diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index d2328035fb..8790a02026 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 399d5dc466..ebc3ed592a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index f7f3bc1905..46ce5870a7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index 7c1c8a03a5..bc921d0dd5 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 858fea62fa..39eb241054 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 49a61287f6..221e74a602 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-wsgi == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-wsgi == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 76b049b7c8..0139ba5fb8 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "wrapt >= 1.12.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index ba23cc0b0a..5b4d838d56 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index 6252ab3de9..b3a56b7976 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml index ebda48982a..22fb150cf8 100644 --- a/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py b/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py index 604195c10e..deef26c62f 100644 --- a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py +++ b/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index 338606aa6e..ee602ead86 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", "packaging >= 21.0", "wrapt >= 1.11.2", ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index 05bda3d1d0..ddc1eb1fab 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-dbapi == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-dbapi == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py index 17627b21dc..db4e3a0022 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 69805b660c..bf087d64d2 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-instrumentation-asgi == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation-asgi == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index aa2d8083ec..6847372597 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "opentelemetry-api ~= 1.11", "psutil ~= 5.9", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 16874b13f9..418bf5e537 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index ea1c48f011..345d226a55 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -24,9 +24,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 62e5da5b54..1d5d30aa45 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 1011912a53..cc1594a31e 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index 17627b21dc..db4e3a0022 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index b5fafc0fe9..e4a6892b23 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index e3e8bca651..32766c2def 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", - "opentelemetry-semantic-conventions == 0.46b0.dev", - "opentelemetry-util-http == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-util-http == 0.47b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py index ff4933b20b..b6955b0eca 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 7e4afad6f7..ff100a1ca6 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -28,54 +28,54 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "opentelemetry-instrumentation-aio-pika==0.46b0.dev", - "opentelemetry-instrumentation-aiohttp-client==0.46b0.dev", - "opentelemetry-instrumentation-aiohttp-server==0.46b0.dev", - "opentelemetry-instrumentation-aiopg==0.46b0.dev", - "opentelemetry-instrumentation-asgi==0.46b0.dev", - "opentelemetry-instrumentation-asyncio==0.46b0.dev", - "opentelemetry-instrumentation-asyncpg==0.46b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.46b0.dev", - "opentelemetry-instrumentation-boto==0.46b0.dev", - "opentelemetry-instrumentation-boto3sqs==0.46b0.dev", - "opentelemetry-instrumentation-botocore==0.46b0.dev", - "opentelemetry-instrumentation-cassandra==0.46b0.dev", - "opentelemetry-instrumentation-celery==0.46b0.dev", - "opentelemetry-instrumentation-confluent-kafka==0.46b0.dev", - "opentelemetry-instrumentation-dbapi==0.46b0.dev", - "opentelemetry-instrumentation-django==0.46b0.dev", - "opentelemetry-instrumentation-elasticsearch==0.46b0.dev", - "opentelemetry-instrumentation-falcon==0.46b0.dev", - "opentelemetry-instrumentation-fastapi==0.46b0.dev", - "opentelemetry-instrumentation-flask==0.46b0.dev", - "opentelemetry-instrumentation-grpc==0.46b0.dev", - "opentelemetry-instrumentation-httpx==0.46b0.dev", - "opentelemetry-instrumentation-jinja2==0.46b0.dev", - "opentelemetry-instrumentation-kafka-python==0.46b0.dev", - "opentelemetry-instrumentation-logging==0.46b0.dev", - "opentelemetry-instrumentation-mysql==0.46b0.dev", - "opentelemetry-instrumentation-mysqlclient==0.46b0.dev", - "opentelemetry-instrumentation-pika==0.46b0.dev", - "opentelemetry-instrumentation-psycopg==0.46b0.dev", - "opentelemetry-instrumentation-psycopg2==0.46b0.dev", - "opentelemetry-instrumentation-pymemcache==0.46b0.dev", - "opentelemetry-instrumentation-pymongo==0.46b0.dev", - "opentelemetry-instrumentation-pymysql==0.46b0.dev", - "opentelemetry-instrumentation-pyramid==0.46b0.dev", - "opentelemetry-instrumentation-redis==0.46b0.dev", - "opentelemetry-instrumentation-remoulade==0.46b0.dev", - "opentelemetry-instrumentation-requests==0.46b0.dev", - "opentelemetry-instrumentation-sklearn==0.46b0.dev", - "opentelemetry-instrumentation-sqlalchemy==0.46b0.dev", - "opentelemetry-instrumentation-sqlite3==0.46b0.dev", - "opentelemetry-instrumentation-starlette==0.46b0.dev", - "opentelemetry-instrumentation-system-metrics==0.46b0.dev", - "opentelemetry-instrumentation-threading==0.46b0.dev", - "opentelemetry-instrumentation-tornado==0.46b0.dev", - "opentelemetry-instrumentation-tortoiseorm==0.46b0.dev", - "opentelemetry-instrumentation-urllib==0.46b0.dev", - "opentelemetry-instrumentation-urllib3==0.46b0.dev", - "opentelemetry-instrumentation-wsgi==0.46b0.dev", + "opentelemetry-instrumentation-aio-pika==0.47b0.dev", + "opentelemetry-instrumentation-aiohttp-client==0.47b0.dev", + "opentelemetry-instrumentation-aiohttp-server==0.47b0.dev", + "opentelemetry-instrumentation-aiopg==0.47b0.dev", + "opentelemetry-instrumentation-asgi==0.47b0.dev", + "opentelemetry-instrumentation-asyncio==0.47b0.dev", + "opentelemetry-instrumentation-asyncpg==0.47b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.47b0.dev", + "opentelemetry-instrumentation-boto==0.47b0.dev", + "opentelemetry-instrumentation-boto3sqs==0.47b0.dev", + "opentelemetry-instrumentation-botocore==0.47b0.dev", + "opentelemetry-instrumentation-cassandra==0.47b0.dev", + "opentelemetry-instrumentation-celery==0.47b0.dev", + "opentelemetry-instrumentation-confluent-kafka==0.47b0.dev", + "opentelemetry-instrumentation-dbapi==0.47b0.dev", + "opentelemetry-instrumentation-django==0.47b0.dev", + "opentelemetry-instrumentation-elasticsearch==0.47b0.dev", + "opentelemetry-instrumentation-falcon==0.47b0.dev", + "opentelemetry-instrumentation-fastapi==0.47b0.dev", + "opentelemetry-instrumentation-flask==0.47b0.dev", + "opentelemetry-instrumentation-grpc==0.47b0.dev", + "opentelemetry-instrumentation-httpx==0.47b0.dev", + "opentelemetry-instrumentation-jinja2==0.47b0.dev", + "opentelemetry-instrumentation-kafka-python==0.47b0.dev", + "opentelemetry-instrumentation-logging==0.47b0.dev", + "opentelemetry-instrumentation-mysql==0.47b0.dev", + "opentelemetry-instrumentation-mysqlclient==0.47b0.dev", + "opentelemetry-instrumentation-pika==0.47b0.dev", + "opentelemetry-instrumentation-psycopg==0.47b0.dev", + "opentelemetry-instrumentation-psycopg2==0.47b0.dev", + "opentelemetry-instrumentation-pymemcache==0.47b0.dev", + "opentelemetry-instrumentation-pymongo==0.47b0.dev", + "opentelemetry-instrumentation-pymysql==0.47b0.dev", + "opentelemetry-instrumentation-pyramid==0.47b0.dev", + "opentelemetry-instrumentation-redis==0.47b0.dev", + "opentelemetry-instrumentation-remoulade==0.47b0.dev", + "opentelemetry-instrumentation-requests==0.47b0.dev", + "opentelemetry-instrumentation-sklearn==0.47b0.dev", + "opentelemetry-instrumentation-sqlalchemy==0.47b0.dev", + "opentelemetry-instrumentation-sqlite3==0.47b0.dev", + "opentelemetry-instrumentation-starlette==0.47b0.dev", + "opentelemetry-instrumentation-system-metrics==0.47b0.dev", + "opentelemetry-instrumentation-threading==0.47b0.dev", + "opentelemetry-instrumentation-tornado==0.47b0.dev", + "opentelemetry-instrumentation-tortoiseorm==0.47b0.dev", + "opentelemetry-instrumentation-urllib==0.47b0.dev", + "opentelemetry-instrumentation-urllib3==0.47b0.dev", + "opentelemetry-instrumentation-wsgi==0.47b0.dev", ] [project.urls] diff --git a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py index ff4933b20b..b6955b0eca 100644 --- a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py +++ b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 0cec60a63f..cf6b3a671b 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -23,13 +23,13 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.46b0.dev", + "opentelemetry-instrumentation == 0.47b0.dev", "opentelemetry-sdk ~= 1.13", ] [project.optional-dependencies] otlp = [ - "opentelemetry-exporter-otlp == 1.25.0.dev", + "opentelemetry-exporter-otlp == 1.26.0.dev", ] [project.entry-points.opentelemetry_configurator] diff --git a/opentelemetry-distro/src/opentelemetry/distro/version.py b/opentelemetry-distro/src/opentelemetry/distro/version.py index ff4933b20b..b6955b0eca 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/version.py +++ b/opentelemetry-distro/src/opentelemetry/distro/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 9eebd5bb38..ea8fa48046 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -18,180 +18,180 @@ libraries = [ { "library": "aio_pika >= 7.2.0, < 10.0.0", - "instrumentation": "opentelemetry-instrumentation-aio-pika==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-aio-pika==0.47b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.47b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.47b0.dev", }, { "library": "aiopg >= 0.13.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiopg==0.47b0.dev", }, { "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-asgi==0.47b0.dev", }, { "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncpg==0.47b0.dev", }, { "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto==0.47b0.dev", }, { "library": "boto3 ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.47b0.dev", }, { "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.47b0.dev", }, { "library": "cassandra-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.47b0.dev", }, { "library": "scylla-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.47b0.dev", }, { "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-celery==0.47b0.dev", }, { "library": "confluent-kafka >= 1.8.2, <= 2.3.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.47b0.dev", }, { "library": "django >= 1.10", - "instrumentation": "opentelemetry-instrumentation-django==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-django==0.47b0.dev", }, { "library": "elasticsearch >= 6.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.47b0.dev", }, { "library": "falcon >= 1.4.1, < 3.1.2", - "instrumentation": "opentelemetry-instrumentation-falcon==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-falcon==0.47b0.dev", }, { "library": "fastapi ~= 0.58", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0.dev", }, { "library": "flask >= 1.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-flask==0.47b0.dev", }, { "library": "grpcio ~= 1.27", - "instrumentation": "opentelemetry-instrumentation-grpc==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-grpc==0.47b0.dev", }, { "library": "httpx >= 0.18.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-httpx==0.47b0.dev", }, { "library": "jinja2 >= 2.7, < 4.0", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-jinja2==0.47b0.dev", }, { "library": "kafka-python >= 2.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.47b0.dev", }, { "library": "mysql-connector-python ~= 8.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysql==0.47b0.dev", }, { "library": "mysqlclient < 3", - "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.47b0.dev", }, { "library": "pika >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-pika==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-pika==0.47b0.dev", }, { "library": "psycopg >= 3.1.0", - "instrumentation": "opentelemetry-instrumentation-psycopg==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg==0.47b0.dev", }, { "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.47b0.dev", }, { "library": "pymemcache >= 1.3.5, < 5", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymemcache==0.47b0.dev", }, { "library": "pymongo >= 3.1, < 5.0", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymongo==0.47b0.dev", }, { "library": "PyMySQL < 2", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymysql==0.47b0.dev", }, { "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-pyramid==0.47b0.dev", }, { "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-redis==0.47b0.dev", }, { "library": "remoulade >= 0.50", - "instrumentation": "opentelemetry-instrumentation-remoulade==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-remoulade==0.47b0.dev", }, { "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-requests==0.47b0.dev", }, { "library": "scikit-learn ~= 0.24.0", - "instrumentation": "opentelemetry-instrumentation-sklearn==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-sklearn==0.47b0.dev", }, { "library": "sqlalchemy", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.47b0.dev", }, { "library": "starlette ~= 0.13.0", - "instrumentation": "opentelemetry-instrumentation-starlette==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-starlette==0.47b0.dev", }, { "library": "psutil >= 5", - "instrumentation": "opentelemetry-instrumentation-system-metrics==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-system-metrics==0.47b0.dev", }, { "library": "tornado >= 5.1.1", - "instrumentation": "opentelemetry-instrumentation-tornado==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-tornado==0.47b0.dev", }, { "library": "tortoise-orm >= 0.17.0", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.47b0.dev", }, { "library": "pydantic >= 1.10.2", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.47b0.dev", }, { "library": "urllib3 >= 1.0.0, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.46b0.dev", + "instrumentation": "opentelemetry-instrumentation-urllib3==0.47b0.dev", }, ] default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.46b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.46b0.dev", - "opentelemetry-instrumentation-dbapi==0.46b0.dev", - "opentelemetry-instrumentation-logging==0.46b0.dev", - "opentelemetry-instrumentation-sqlite3==0.46b0.dev", - "opentelemetry-instrumentation-threading==0.46b0.dev", - "opentelemetry-instrumentation-urllib==0.46b0.dev", - "opentelemetry-instrumentation-wsgi==0.46b0.dev", + "opentelemetry-instrumentation-asyncio==0.47b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.47b0.dev", + "opentelemetry-instrumentation-dbapi==0.47b0.dev", + "opentelemetry-instrumentation-logging==0.47b0.dev", + "opentelemetry-instrumentation-sqlite3==0.47b0.dev", + "opentelemetry-instrumentation-threading==0.47b0.dev", + "opentelemetry-instrumentation-urllib==0.47b0.dev", + "opentelemetry-instrumentation-wsgi==0.47b0.dev", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index ff4933b20b..b6955b0eca 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py index ff4933b20b..b6955b0eca 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py index ff4933b20b..b6955b0eca 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py index ff4933b20b..b6955b0eca 100644 --- a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py +++ b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py index ff4933b20b..b6955b0eca 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.46b0.dev" +__version__ = "0.47b0.dev" From 55c829b6c4b86b0b62405369f75270e8c00b907e Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Fri, 31 May 2024 09:04:58 -0700 Subject: [PATCH 022/335] Update release.yml --- .github/workflows/release.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b60ebc7599..ec544b43c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,12 +81,14 @@ jobs: # rejected by pypi (e.g "3 - Beta"). This would cause a failure during the # middle of the package upload causing the action to fail, and certain packages # might have already been updated, this would be bad. - - name: Publish to TestPyPI - env: - TWINE_USERNAME: '__token__' - TWINE_PASSWORD: ${{ secrets.test_pypi_token }} - run: | - twine upload --repository testpypi --skip-existing --verbose dist/* + # EDIT: 5/31/2024 - TestPypi now requires a verified email. Commenting out as a temporary measure + # until we found TestPypi credentials. + # - name: Publish to TestPyPI + # env: + # TWINE_USERNAME: '__token__' + # TWINE_PASSWORD: ${{ secrets.test_pypi_token }} + # run: | + # twine upload --repository testpypi --skip-existing --verbose dist/* - name: Publish to PyPI env: From 73d0fa46a98edebf50acfee3897346913ec8129c Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 31 May 2024 19:00:14 +0200 Subject: [PATCH 023/335] Copy change log updates from release/v1.25.x-0.46bx (#2571) --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 778f16c54b..eca19d3fa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version - ([#2500](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500)) - `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) -## Version 1.25.0/0.46b0 (2024-05-30) +## Version 1.25.0/0.46b0 (2024-05-31) ### Breaking changes @@ -51,6 +49,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `opentelemetry-instrumentation-dbapi` Fix compatibility with Psycopg3 to extract libpq build version + ([#2500](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2500)) - `opentelemetry-instrumentation-grpc` AioClientInterceptor should propagate with a Metadata object ([#2363](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2363)) - `opentelemetry-instrumentation-boto3sqs` Instrument Session and resource From ed51ebb312fa571ee5a07af871443d97915b89fe Mon Sep 17 00:00:00 2001 From: Pavel Perestoronin Date: Mon, 3 Jun 2024 19:18:47 +0200 Subject: [PATCH 024/335] feat(asgi,fastapi,starlette)!: provide both send and receive hooks with `scope` and `message` (#2546) --- CHANGELOG.md | 1 + .../instrumentation/asgi/__init__.py | 37 +++++++------- .../instrumentation/asgi/types.py | 49 +++++++++++++++++++ .../tests/test_asgi_middleware.py | 6 +-- .../instrumentation/fastapi/__init__.py | 33 ++++++------- .../tests/test_fastapi_instrumentation.py | 12 ++--- .../instrumentation/starlette/__init__.py | 35 ++++++------- .../tests/test_starlette_instrumentation.py | 12 ++--- 8 files changed, 118 insertions(+), 67 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/types.py diff --git a/CHANGELOG.md b/CHANGELOG.md index eca19d3fa8..b92f0c62c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2425](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2425)) - `opentelemetry-instrumentation-flask` Add `http.method` to `span.name` ([#2454](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2454)) +- ASGI, FastAPI, Starlette: provide both send and receive hooks with `scope` and `message` for internal spans ([#2546](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2546)) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 405c470ceb..8edb3420b1 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -81,15 +81,15 @@ async def hello(): .. code-block:: python - def server_request_hook(span: Span, scope: dict): + def server_request_hook(span: Span, scope: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_request_hook", "some-value") - def client_request_hook(span: Span, scope: dict): + def client_request_hook(span: Span, scope: dict[str, Any], message: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_client_request_hook", "some-value") - def client_response_hook(span: Span, message: dict): + def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_response_hook", "some-value") @@ -200,6 +200,11 @@ def client_response_hook(span: Span, message: dict): from asgiref.compatibility import guarantee_single_callable from opentelemetry import context, trace +from opentelemetry.instrumentation.asgi.types import ( + ClientRequestHook, + ClientResponseHook, + ServerRequestHook, +) from opentelemetry.instrumentation.asgi.version import __version__ # noqa from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, @@ -212,7 +217,7 @@ def client_response_hook(span: Span, message: dict): from opentelemetry.propagators.textmap import Getter, Setter from opentelemetry.semconv.metrics import MetricInstruments from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import Span, set_span_in_context +from opentelemetry.trace import set_span_in_context from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import ( OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, @@ -227,10 +232,6 @@ def client_response_hook(span: Span, message: dict): remove_url_credentials, ) -_ServerRequestHookT = typing.Optional[typing.Callable[[Span, dict], None]] -_ClientRequestHookT = typing.Optional[typing.Callable[[Span, dict], None]] -_ClientResponseHookT = typing.Optional[typing.Callable[[Span, dict], None]] - class ASGIGetter(Getter[dict]): def get( @@ -454,10 +455,10 @@ class OpenTelemetryMiddleware: Optional: Defaults to get_default_span_details. server_request_hook: Optional callback which is called with the server span and ASGI scope object for every incoming request. - client_request_hook: Optional callback which is called with the internal span and an ASGI - scope which is sent as a dictionary for when the method receive is called. - client_response_hook: Optional callback which is called with the internal span and an ASGI - event which is sent as a dictionary for when the method send is called. + client_request_hook: Optional callback which is called with the internal span, and ASGI + scope and event which are sent as dictionaries for when the method receive is called. + client_response_hook: Optional callback which is called with the internal span, and ASGI + scope and event which are sent as dictionaries for when the method send is called. tracer_provider: The optional tracer provider to use. If omitted the current globally configured one is used. """ @@ -468,9 +469,9 @@ def __init__( app, excluded_urls=None, default_span_details=None, - server_request_hook: _ServerRequestHookT = None, - client_request_hook: _ClientRequestHookT = None, - client_response_hook: _ClientResponseHookT = None, + server_request_hook: ServerRequestHook = None, + client_request_hook: ClientRequestHook = None, + client_response_hook: ClientResponseHook = None, tracer_provider=None, meter_provider=None, meter=None, @@ -666,9 +667,9 @@ async def otel_receive(): with self.tracer.start_as_current_span( " ".join((server_span_name, scope["type"], "receive")) ) as receive_span: - if callable(self.client_request_hook): - self.client_request_hook(receive_span, scope) message = await receive() + if callable(self.client_request_hook): + self.client_request_hook(receive_span, scope, message) if receive_span.is_recording(): if message["type"] == "websocket.receive": set_status_code(receive_span, 200) @@ -691,7 +692,7 @@ async def otel_send(message: dict[str, Any]): " ".join((server_span_name, scope["type"], "send")) ) as send_span: if callable(self.client_response_hook): - self.client_response_hook(send_span, message) + self.client_response_hook(send_span, scope, message) if send_span.is_recording(): if message["type"] == "http.response.start": status_code = message["status"] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/types.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/types.py new file mode 100644 index 0000000000..bc0c11afc9 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/types.py @@ -0,0 +1,49 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Any, Callable, Dict, Optional + +from opentelemetry.trace import Span + +_Scope = Dict[str, Any] +_Message = Dict[str, Any] + +ServerRequestHook = Optional[Callable[[Span, _Scope], None]] +""" +Incoming request callback type. + +Args: + - Server span + - ASGI scope as a mapping +""" + +ClientRequestHook = Optional[Callable[[Span, _Scope, _Message], None]] +""" +Receive callback type. + +Args: + - Internal span + - ASGI scope as a mapping + - ASGI event as a mapping +""" + +ClientResponseHook = Optional[Callable[[Span, _Scope, _Message], None]] +""" +Send callback type. + +Args: + - Internal span + - ASGI scope as a mapping + - ASGI event as a mapping +""" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index 2a8fd1c1f0..902cd4ec7e 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -683,10 +683,10 @@ def test_hooks(self): def server_request_hook(span, scope): span.update_name("name from server hook") - def client_request_hook(recieve_span, request): - recieve_span.update_name("name from client request hook") + def client_request_hook(receive_span, scope, message): + receive_span.update_name("name from client request hook") - def client_response_hook(send_span, response): + def client_response_hook(send_span, scope, message): send_span.set_attribute("attr-from-hook", "value") def update_expected_hook_results(expected): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 10b73c7a5b..6f52c6ef3b 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -59,20 +59,20 @@ async def foobar(): right after a span is created for a request and right before the span is finished for the response. - The server request hook is passed a server span and ASGI scope object for every incoming request. -- The client request hook is called with the internal span and an ASGI scope when the method ``receive`` is called. -- The client response hook is called with the internal span and an ASGI event when the method ``send`` is called. +- The client request hook is called with the internal span, and ASGI scope and event when the method ``receive`` is called. +- The client response hook is called with the internal span, and ASGI scope and event when the method ``send`` is called. .. code-block:: python - def server_request_hook(span: Span, scope: dict): + def server_request_hook(span: Span, scope: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_request_hook", "some-value") - def client_request_hook(span: Span, scope: dict): + def client_request_hook(span: Span, scope: dict[str, Any], message: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_client_request_hook", "some-value") - def client_response_hook(span: Span, message: dict): + def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_response_hook", "some-value") @@ -172,28 +172,27 @@ def client_response_hook(span: Span, message: dict): --- """ import logging -import typing from typing import Collection import fastapi from starlette.routing import Match from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware +from opentelemetry.instrumentation.asgi.types import ( + ClientRequestHook, + ClientResponseHook, + ServerRequestHook, +) from opentelemetry.instrumentation.fastapi.package import _instruments from opentelemetry.instrumentation.fastapi.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.metrics import get_meter from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import Span from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls _excluded_urls_from_env = get_excluded_urls("FASTAPI") _logger = logging.getLogger(__name__) -_ServerRequestHookT = typing.Optional[typing.Callable[[Span, dict], None]] -_ClientRequestHookT = typing.Optional[typing.Callable[[Span, dict], None]] -_ClientResponseHookT = typing.Optional[typing.Callable[[Span, dict], None]] - class FastAPIInstrumentor(BaseInstrumentor): """An instrumentor for FastAPI @@ -206,9 +205,9 @@ class FastAPIInstrumentor(BaseInstrumentor): @staticmethod def instrument_app( app: fastapi.FastAPI, - server_request_hook: _ServerRequestHookT = None, - client_request_hook: _ClientRequestHookT = None, - client_response_hook: _ClientResponseHookT = None, + server_request_hook: ServerRequestHook = None, + client_request_hook: ClientRequestHook = None, + client_response_hook: ClientResponseHook = None, tracer_provider=None, meter_provider=None, excluded_urls=None, @@ -292,9 +291,9 @@ class _InstrumentedFastAPI(fastapi.FastAPI): _tracer_provider = None _meter_provider = None _excluded_urls = None - _server_request_hook: _ServerRequestHookT = None - _client_request_hook: _ClientRequestHookT = None - _client_response_hook: _ClientResponseHookT = None + _server_request_hook: ServerRequestHook = None + _client_request_hook: ClientRequestHook = None + _client_response_hook: ClientResponseHook = None _instrumented_fastapi_apps = set() def __init__(self, *args, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index f9261ad5db..5cf9a0d590 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -342,23 +342,23 @@ def server_request_hook(self, span, scope): if self._server_request_hook is not None: self._server_request_hook(span, scope) - def client_request_hook(self, receive_span, request): + def client_request_hook(self, receive_span, scope, message): if self._client_request_hook is not None: - self._client_request_hook(receive_span, request) + self._client_request_hook(receive_span, scope, message) - def client_response_hook(self, send_span, response): + def client_response_hook(self, send_span, scope, message): if self._client_response_hook is not None: - self._client_response_hook(send_span, response) + self._client_response_hook(send_span, scope, message) def test_hooks(self): def server_request_hook(span, scope): span.update_name("name from server hook") - def client_request_hook(receive_span, request): + def client_request_hook(receive_span, scope, message): receive_span.update_name("name from client hook") receive_span.set_attribute("attr-from-request-hook", "set") - def client_response_hook(send_span, response): + def client_response_hook(send_span, scope, message): send_span.update_name("name from response hook") send_span.set_attribute("attr-from-response-hook", "value") diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index 1ebc3348d4..83f5b5c52b 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -55,20 +55,22 @@ def home(request): right after a span is created for a request and right before the span is finished for the response. - The server request hook is passed a server span and ASGI scope object for every incoming request. -- The client request hook is called with the internal span and an ASGI scope when the method ``receive`` is called. -- The client response hook is called with the internal span and an ASGI event when the method ``send`` is called. +- The client request hook is called with the internal span, and ASGI scope and event when the method ``receive`` is called. +- The client response hook is called with the internal span, and ASGI scope and event when the method ``send`` is called. For example, .. code-block:: python - def server_request_hook(span: Span, scope: dict): + def server_request_hook(span: Span, scope: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_request_hook", "some-value") - def client_request_hook(span: Span, scope: dict): + + def client_request_hook(span: Span, scope: dict[str, Any], message: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_client_request_hook", "some-value") - def client_response_hook(span: Span, message: dict): + + def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, Any]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_response_hook", "some-value") @@ -167,27 +169,26 @@ def client_response_hook(span: Span, message: dict): API --- """ -import typing from typing import Collection from starlette import applications from starlette.routing import Match from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware +from opentelemetry.instrumentation.asgi.types import ( + ClientRequestHook, + ClientResponseHook, + ServerRequestHook, +) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.starlette.package import _instruments from opentelemetry.instrumentation.starlette.version import __version__ from opentelemetry.metrics import get_meter from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import Span from opentelemetry.util.http import get_excluded_urls _excluded_urls = get_excluded_urls("STARLETTE") -_ServerRequestHookT = typing.Optional[typing.Callable[[Span, dict], None]] -_ClientRequestHookT = typing.Optional[typing.Callable[[Span, dict], None]] -_ClientResponseHookT = typing.Optional[typing.Callable[[Span, dict], None]] - class StarletteInstrumentor(BaseInstrumentor): """An instrumentor for starlette @@ -200,9 +201,9 @@ class StarletteInstrumentor(BaseInstrumentor): @staticmethod def instrument_app( app: applications.Starlette, - server_request_hook: _ServerRequestHookT = None, - client_request_hook: _ClientRequestHookT = None, - client_response_hook: _ClientResponseHookT = None, + server_request_hook: ServerRequestHook = None, + client_request_hook: ClientRequestHook = None, + client_response_hook: ClientResponseHook = None, meter_provider=None, tracer_provider=None, ): @@ -270,9 +271,9 @@ def _uninstrument(self, **kwargs): class _InstrumentedStarlette(applications.Starlette): _tracer_provider = None _meter_provider = None - _server_request_hook: _ServerRequestHookT = None - _client_request_hook: _ClientRequestHookT = None - _client_response_hook: _ClientResponseHookT = None + _server_request_hook: ServerRequestHook = None + _client_request_hook: ClientRequestHook = None + _client_response_hook: ClientResponseHook = None _instrumented_starlette_apps = set() def __init__(self, *args, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py index 3784672fb5..0accda18fd 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -263,23 +263,23 @@ def server_request_hook(self, span, scope): if self._server_request_hook is not None: self._server_request_hook(span, scope) - def client_request_hook(self, receive_span, request): + def client_request_hook(self, receive_span, scope, message): if self._client_request_hook is not None: - self._client_request_hook(receive_span, request) + self._client_request_hook(receive_span, scope, message) - def client_response_hook(self, send_span, response): + def client_response_hook(self, send_span, scope, message): if self._client_response_hook is not None: - self._client_response_hook(send_span, response) + self._client_response_hook(send_span, scope, message) def test_hooks(self): def server_request_hook(span, scope): span.update_name("name from server hook") - def client_request_hook(receive_span, request): + def client_request_hook(receive_span, scope, message): receive_span.update_name("name from client hook") receive_span.set_attribute("attr-from-request-hook", "set") - def client_response_hook(send_span, response): + def client_response_hook(send_span, scope, message): send_span.update_name("name from response hook") send_span.set_attribute("attr-from-response-hook", "value") From 768694cf7578e6a211c42049c85ef7227eea6b48 Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:20:09 -0700 Subject: [PATCH 025/335] add processor directory to build.sh (#2574) --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 247bb24b4e..93dc0edce1 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -16,7 +16,7 @@ DISTDIR=dist mkdir -p $DISTDIR rm -rf ${DISTDIR:?}/* - for d in exporter/*/ opentelemetry-instrumentation/ opentelemetry-contrib-instrumentations/ opentelemetry-distro/ instrumentation/*/ propagator/*/ resource/*/ sdk-extension/*/ util/*/ ; do + for d in exporter/*/ opentelemetry-instrumentation/ opentelemetry-contrib-instrumentations/ opentelemetry-distro/ instrumentation/*/ processor/*/ propagator/*/ resource/*/ sdk-extension/*/ util/*/ ; do ( echo "building $d" cd "$d" From c06fd1dd534513ae26c16ed5eb5916a5f8eb4cf0 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 4 Jun 2024 09:19:48 -0700 Subject: [PATCH 026/335] Update README.rst (#2575) --- .../opentelemetry-processor-baggage/README.rst | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/processor/opentelemetry-processor-baggage/README.rst b/processor/opentelemetry-processor-baggage/README.rst index a111166cef..83c4e91edf 100644 --- a/processor/opentelemetry-processor-baggage/README.rst +++ b/processor/opentelemetry-processor-baggage/README.rst @@ -1,10 +1,22 @@ OpenTelemetry Baggage Span Processor ==================================== +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-processor-baggage.svg + :target: https://pypi.org/project/opentelemetry-processor-baggage/ + The BaggageSpanProcessor reads entries stored in Baggage from the parent context and adds the baggage entries' keys and values to the span as attributes on span start. +Installation +------------ + +:: + + pip install opentelemetry-processor-baggage + Add this span processor to a tracer provider. Keys and values added to Baggage will appear on subsequent child @@ -48,4 +60,4 @@ For example, to only copy baggage entries that match the regex `^key.+`: ```python regex_predicate = lambda baggage_key: baggage_key.startswith("^key.+") tracer_provider.add_span_processor(BaggageSpanProcessor(regex_predicate)) -``` \ No newline at end of file +``` From 95fea2bfa7eb885912752ca954db0711f96c8ab5 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 5 Jun 2024 20:14:44 +0200 Subject: [PATCH 027/335] Fix running async psycopg tests (#2540) --- .../test-requirements.txt | 1 - .../tests/test_aio_client_interceptor.py | 18 +- .../test_aio_client_interceptor_filter.py | 20 +- .../test_aio_client_interceptor_hooks.py | 18 +- .../tests/test_aio_server_interceptor.py | 19 +- .../test_aio_server_interceptor_filter.py | 18 +- .../tests/test_psycopg_integration.py | 219 +++++++++--------- tox.ini | 1 - 8 files changed, 120 insertions(+), 194 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt index 56d47af0df..9303dc27c0 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt @@ -10,7 +10,6 @@ protobuf==3.20.3 py==1.11.0 py-cpuinfo==9.0.0 pytest==7.1.3 -pytest-asyncio==0.23.5 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py index 21dbc44066..7ae1649149 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py @@ -11,24 +11,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -try: - from unittest import IsolatedAsyncioTestCase -except ImportError: - # unittest.IsolatedAsyncioTestCase was introduced in Python 3.8. It's use - # simplifies the following tests. Without it, the amount of test code - # increases significantly, with most of the additional code handling - # the asyncio set up. - from unittest import TestCase - - class IsolatedAsyncioTestCase(TestCase): - def run(self, result=None): - self.skipTest( - "This test requires Python 3.8 for unittest.IsolatedAsyncioTestCase" - ) - +from unittest import IsolatedAsyncioTestCase import grpc -import pytest import opentelemetry.instrumentation.grpc from opentelemetry import trace @@ -65,7 +50,6 @@ async def intercept_unary_unary( return await continuation(client_call_details, request) -@pytest.mark.asyncio class TestAioClientInterceptor(TestBase, IsolatedAsyncioTestCase): def setUp(self): super().setUp() diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_filter.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_filter.py index b8c408c6cf..2bd68fd492 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_filter.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_filter.py @@ -11,27 +11,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -try: - from unittest import IsolatedAsyncioTestCase -except ImportError: - # unittest.IsolatedAsyncioTestCase was introduced in Python 3.8. It's use - # simplifies the following tests. Without it, the amount of test code - # increases significantly, with most of the additional code handling - # the asyncio set up. - from unittest import TestCase - - class IsolatedAsyncioTestCase(TestCase): - def run(self, result=None): - self.skipTest( - "This test requires Python 3.8 for unittest.IsolatedAsyncioTestCase" - ) - - import os -from unittest import mock +from unittest import IsolatedAsyncioTestCase, mock import grpc -import pytest from opentelemetry.instrumentation.grpc import ( GrpcAioInstrumentorClient, @@ -50,7 +33,6 @@ def run(self, result=None): from .protobuf import test_server_pb2_grpc # pylint: disable=no-name-in-module -@pytest.mark.asyncio class TestAioClientInterceptorFiltered(TestBase, IsolatedAsyncioTestCase): def setUp(self): super().setUp() diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py index 9086d8b0f7..40c2334ae7 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor_hooks.py @@ -11,24 +11,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -try: - from unittest import IsolatedAsyncioTestCase -except ImportError: - # unittest.IsolatedAsyncioTestCase was introduced in Python 3.8. It's use - # simplifies the following tests. Without it, the amount of test code - # increases significantly, with most of the additional code handling - # the asyncio set up. - from unittest import TestCase - - class IsolatedAsyncioTestCase(TestCase): - def run(self, result=None): - self.skipTest( - "This test requires Python 3.8 for unittest.IsolatedAsyncioTestCase" - ) - +from unittest import IsolatedAsyncioTestCase import grpc -import pytest from opentelemetry.instrumentation.grpc import GrpcAioInstrumentorClient from opentelemetry.test.test_base import TestBase @@ -54,7 +39,6 @@ def response_hook_with_exception(_span, _response): raise Exception() # pylint: disable=broad-exception-raised -@pytest.mark.asyncio class TestAioClientInterceptorWithHooks(TestBase, IsolatedAsyncioTestCase): def setUp(self): super().setUp() diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py index 7b31b085de..050f6f8d13 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py @@ -12,26 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio - -try: - from unittest import IsolatedAsyncioTestCase -except ImportError: - # unittest.IsolatedAsyncioTestCase was introduced in Python 3.8. It's use - # simplifies the following tests. Without it, the amount of test code - # increases significantly, with most of the additional code handling - # the asyncio set up. - from unittest import TestCase - - class IsolatedAsyncioTestCase(TestCase): - def run(self, result=None): - self.skipTest( - "This test requires Python 3.8 for unittest.IsolatedAsyncioTestCase" - ) - +from unittest import IsolatedAsyncioTestCase import grpc import grpc.aio -import pytest import opentelemetry.instrumentation.grpc from opentelemetry import trace @@ -97,7 +81,6 @@ async def run_with_test_server( return resp -@pytest.mark.asyncio class TestOpenTelemetryAioServerInterceptor(TestBase, IsolatedAsyncioTestCase): async def test_instrumentor(self): """Check that automatic instrumentation configures the interceptor""" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor_filter.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor_filter.py index 837d9c7618..34b755ced8 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor_filter.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor_filter.py @@ -11,25 +11,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -try: - from unittest import IsolatedAsyncioTestCase -except ImportError: - # unittest.IsolatedAsyncioTestCase was introduced in Python 3.8. It's use - # simplifies the following tests. Without it, the amount of test code - # increases significantly, with most of the additional code handling - # the asyncio set up. - from unittest import TestCase - - class IsolatedAsyncioTestCase(TestCase): - def run(self, result=None): - self.skipTest( - "This test requires Python 3.8 for unittest.IsolatedAsyncioTestCase" - ) - +from unittest import IsolatedAsyncioTestCase import grpc import grpc.aio -import pytest from opentelemetry import trace from opentelemetry.instrumentation.grpc import ( @@ -68,7 +53,6 @@ async def run_with_test_server( return resp -@pytest.mark.asyncio class TestOpenTelemetryAioServerInterceptor(TestBase, IsolatedAsyncioTestCase): async def test_instrumentor(self): """Check that automatic instrumentation configures the interceptor""" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py index e2b3ed917a..5a5b39d80b 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py @@ -12,9 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import asyncio import types -from unittest import mock +from unittest import IsolatedAsyncioTestCase, mock import psycopg @@ -114,6 +113,10 @@ def cursor(self): return cur return MockAsyncCursor() + def execute(self, query, params=None, *, prepare=None, binary=False): + cur = self.cursor() + return cur.execute(query, params, prepare=prepare) + def get_dsn_parameters(self): # pylint: disable=no-self-use return {"dbname": "test"} @@ -124,7 +127,8 @@ async def __aexit__(self, *args): return mock.MagicMock(spec=types.MethodType) -class TestPostgresqlIntegration(TestBase): +class PostgresqlIntegrationTestMixin: + # pylint: disable=invalid-name def setUp(self): super().setUp() self.cursor_mock = mock.patch( @@ -148,6 +152,7 @@ def setUp(self): self.connection_sync_mock.start() self.connection_async_mock.start() + # pylint: disable=invalid-name def tearDown(self): super().tearDown() self.memory_exporter.clear() @@ -159,6 +164,8 @@ def tearDown(self): with self.disable_logging(): PsycopgInstrumentor().uninstrument() + +class TestPostgresqlIntegration(PostgresqlIntegrationTestMixin, TestBase): # pylint: disable=unused-argument def test_instrumentor(self): PsycopgInstrumentor().instrument() @@ -221,60 +228,6 @@ def test_instrumentor_with_connection_class(self): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 1) - async def test_wrap_async_connection_class_with_cursor(self): - PsycopgInstrumentor().instrument() - - async def test_async_connection(): - acnx = await psycopg.AsyncConnection.connect(database="test") - async with acnx as cnx: - async with cnx.cursor() as cursor: - await cursor.execute("SELECT * FROM test") - - asyncio.run(test_async_connection()) - spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 1) - span = spans_list[0] - - # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( - span, opentelemetry.instrumentation.psycopg - ) - - # check that no spans are generated after uninstrument - PsycopgInstrumentor().uninstrument() - - asyncio.run(test_async_connection()) - - spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 1) - - # pylint: disable=unused-argument - async def test_instrumentor_with_async_connection_class(self): - PsycopgInstrumentor().instrument() - - async def test_async_connection(): - acnx = await psycopg.AsyncConnection.connect(database="test") - async with acnx as cnx: - await cnx.execute("SELECT * FROM test") - - asyncio.run(test_async_connection()) - - spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 1) - span = spans_list[0] - - # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( - span, opentelemetry.instrumentation.psycopg - ) - - # check that no spans are generated after uninstrument - PsycopgInstrumentor().uninstrument() - asyncio.run(test_async_connection()) - - spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 1) - def test_span_name(self): PsycopgInstrumentor().instrument() @@ -301,33 +254,6 @@ def test_span_name(self): self.assertEqual(spans_list[4].name, "query") self.assertEqual(spans_list[5].name, "query") - async def test_span_name_async(self): - PsycopgInstrumentor().instrument() - - cnx = psycopg.AsyncConnection.connect(database="test") - async with cnx.cursor() as cursor: - await cursor.execute("Test query", ("param1Value", False)) - await cursor.execute( - """multi - line - query""" - ) - await cursor.execute("tab\tseparated query") - await cursor.execute("/* leading comment */ query") - await cursor.execute( - "/* leading comment */ query /* trailing comment */" - ) - await cursor.execute("query /* trailing comment */") - - spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 6) - self.assertEqual(spans_list[0].name, "Test") - self.assertEqual(spans_list[1].name, "multi") - self.assertEqual(spans_list[2].name, "tab") - self.assertEqual(spans_list[3].name, "query") - self.assertEqual(spans_list[4].name, "query") - self.assertEqual(spans_list[5].name, "query") - # pylint: disable=unused-argument def test_not_recording(self): mock_tracer = mock.Mock() @@ -348,26 +274,6 @@ def test_not_recording(self): PsycopgInstrumentor().uninstrument() - # pylint: disable=unused-argument - async def test_not_recording_async(self): - mock_tracer = mock.Mock() - mock_span = mock.Mock() - mock_span.is_recording.return_value = False - mock_tracer.start_span.return_value = mock_span - PsycopgInstrumentor().instrument() - with mock.patch("opentelemetry.trace.get_tracer") as tracer: - tracer.return_value = mock_tracer - cnx = psycopg.AsyncConnection.connect(database="test") - async with cnx.cursor() as cursor: - query = "SELECT * FROM test" - cursor.execute(query) - self.assertFalse(mock_span.is_recording()) - self.assertTrue(mock_span.is_recording.called) - self.assertFalse(mock_span.set_attribute.called) - self.assertFalse(mock_span.set_status.called) - - PsycopgInstrumentor().uninstrument() - # pylint: disable=unused-argument def test_custom_tracer_provider(self): resource = resources.Resource.create({}) @@ -477,3 +383,108 @@ def test_sqlcommenter_disabled(self, event_mocked): cursor.execute(query) kwargs = event_mocked.call_args[1] self.assertEqual(kwargs["enable_commenter"], False) + + +class TestPostgresqlIntegrationAsync( + PostgresqlIntegrationTestMixin, TestBase, IsolatedAsyncioTestCase +): + async def test_wrap_async_connection_class_with_cursor(self): + PsycopgInstrumentor().instrument() + + async def test_async_connection(): + acnx = await psycopg.AsyncConnection.connect("test") + async with acnx as cnx: + async with cnx.cursor() as cursor: + await cursor.execute("SELECT * FROM test") + + await test_async_connection() + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + + # Check version and name in span's instrumentation info + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.psycopg + ) + + # check that no spans are generated after uninstrument + PsycopgInstrumentor().uninstrument() + + await test_async_connection() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + + # pylint: disable=unused-argument + async def test_instrumentor_with_async_connection_class(self): + PsycopgInstrumentor().instrument() + + async def test_async_connection(): + acnx = await psycopg.AsyncConnection.connect("test") + async with acnx as cnx: + await cnx.execute("SELECT * FROM test") + + await test_async_connection() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + + # Check version and name in span's instrumentation info + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.psycopg + ) + + # check that no spans are generated after uninstrument + PsycopgInstrumentor().uninstrument() + await test_async_connection() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + + async def test_span_name_async(self): + PsycopgInstrumentor().instrument() + + cnx = await psycopg.AsyncConnection.connect("test") + async with cnx.cursor() as cursor: + await cursor.execute("Test query", ("param1Value", False)) + await cursor.execute( + """multi + line + query""" + ) + await cursor.execute("tab\tseparated query") + await cursor.execute("/* leading comment */ query") + await cursor.execute( + "/* leading comment */ query /* trailing comment */" + ) + await cursor.execute("query /* trailing comment */") + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 6) + self.assertEqual(spans_list[0].name, "Test") + self.assertEqual(spans_list[1].name, "multi") + self.assertEqual(spans_list[2].name, "tab") + self.assertEqual(spans_list[3].name, "query") + self.assertEqual(spans_list[4].name, "query") + self.assertEqual(spans_list[5].name, "query") + + # pylint: disable=unused-argument + async def test_not_recording_async(self): + mock_tracer = mock.Mock() + mock_span = mock.Mock() + mock_span.is_recording.return_value = False + mock_tracer.start_span.return_value = mock_span + PsycopgInstrumentor().instrument() + with mock.patch("opentelemetry.trace.get_tracer") as tracer: + tracer.return_value = mock_tracer + cnx = await psycopg.AsyncConnection.connect("test") + async with cnx.cursor() as cursor: + query = "SELECT * FROM test" + await cursor.execute(query) + self.assertFalse(mock_span.is_recording()) + self.assertTrue(mock_span.is_recording.called) + self.assertFalse(mock_span.set_attribute.called) + self.assertFalse(mock_span.set_status.called) + + PsycopgInstrumentor().uninstrument() diff --git a/tox.ini b/tox.ini index e97476a850..63c80083d4 100644 --- a/tox.ini +++ b/tox.ini @@ -373,7 +373,6 @@ deps = test: pytest-benchmark coverage: pytest coverage: pytest-cov - grpc: pytest-asyncio ; FIXME: add coverage testing ; FIXME: add mypy testing From e306aba7ecf6aac9c1ae4130514886205e696045 Mon Sep 17 00:00:00 2001 From: soumyadeepm04 <84105194+soumyadeepm04@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:35:48 -0400 Subject: [PATCH 028/335] removed references to [test] extras from eachdist script (#2578) --- scripts/eachdist.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/scripts/eachdist.py b/scripts/eachdist.py index 570a0cd0e5..2eaabee2c7 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -198,7 +198,6 @@ def setup_instparser(instparser): setup_instparser(instparser) instparser.add_argument("--editable", "-e", action="store_true") - instparser.add_argument("--with-test-deps", action="store_true") instparser.add_argument("--with-dev-deps", action="store_true") instparser.add_argument("--eager-upgrades", action="store_true") @@ -211,7 +210,6 @@ def setup_instparser(instparser): editable=True, with_dev_deps=True, eager_upgrades=True, - with_test_deps=True, ) lintparser = subparsers.add_parser( @@ -467,16 +465,7 @@ def install_args(args): check=True, ) - allfmt = "-e 'file://{}" if args.editable else "'file://{}" - # packages should provide an extra_requires that is named - # 'test', to denote test dependencies. - extras = [] - if args.with_test_deps: - extras.append("test") - if extras: - allfmt += f"[{','.join(extras)}]" - # note the trailing single quote, to close the quote opened above. - allfmt += "'" + allfmt = "-e 'file://{}'" if args.editable else "'file://{}'" execute_args( parse_subargs( @@ -489,6 +478,7 @@ def install_args(args): ), ) ) + if args.with_dev_deps: rootpath = find_projectroot() runsubprocess( From bb9eebb73e1b225c8d958eb5bf6c3a90fa434311 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 5 Jun 2024 15:27:12 -0700 Subject: [PATCH 029/335] Fix readme formatting and markdown (#2576) --- .../README.rst | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/processor/opentelemetry-processor-baggage/README.rst b/processor/opentelemetry-processor-baggage/README.rst index 83c4e91edf..6d3a439d8a 100644 --- a/processor/opentelemetry-processor-baggage/README.rst +++ b/processor/opentelemetry-processor-baggage/README.rst @@ -26,7 +26,7 @@ configured. If the external services also have a Baggage span processor, the keys and values will appear in those child spans as well. -⚠ Warning ⚠️ +[!WARNING] Do not put sensitive information in Baggage. @@ -39,25 +39,32 @@ Add the span processor when configuring the tracer provider. To configure the span processor to copy all baggage entries during configuration: -```python -from opentelemetry.processor.baggage import BaggageSpanProcessor, ALLOW_ALL_BAGGAGE_KEYS +:: + + from opentelemetry.processor.baggage import BaggageSpanProcessor, ALLOW_ALL_BAGGAGE_KEYS + + tracer_provider = TracerProvider() + tracer_provider.add_span_processor(BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS)) -tracer_provider = TracerProvider() -tracer_provider.add_span_processor(BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS)) -``` Alternatively, you can provide a custom baggage key predicate to select which baggage keys you want to copy. For example, to only copy baggage entries that start with `my-key`: -```python -starts_with_predicate = lambda baggage_key: baggage_key.startswith("my-key") -tracer_provider.add_span_processor(BaggageSpanProcessor(starts_with_predicate)) -``` +:: + + starts_with_predicate = lambda baggage_key: baggage_key.startswith("my-key") + tracer_provider.add_span_processor(BaggageSpanProcessor(starts_with_predicate)) + For example, to only copy baggage entries that match the regex `^key.+`: -```python -regex_predicate = lambda baggage_key: baggage_key.startswith("^key.+") -tracer_provider.add_span_processor(BaggageSpanProcessor(regex_predicate)) -``` +:: + + regex_predicate = lambda baggage_key: baggage_key.startswith("^key.+") + tracer_provider.add_span_processor(BaggageSpanProcessor(regex_predicate)) + + +References +---------- +* `OpenTelemetry Project `_ From 5b841282ab9ac5303fd165a746ac3724b6ac5984 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 6 Jun 2024 12:52:32 -0700 Subject: [PATCH 030/335] Do not use `asgi` name and version for tracer/meter for instrumentations using Asgi Middleware (#2580) --- CHANGELOG.md | 5 +++++ .../instrumentation/asgi/__init__.py | 17 ++++++++++++----- .../tests/test_asgi_middleware.py | 8 ++++++++ .../instrumentation/fastapi/__init__.py | 19 +++++++++++++++++-- .../tests/test_fastapi_instrumentation.py | 8 ++++++++ .../instrumentation/starlette/__init__.py | 19 +++++++++++++++++-- .../tests/test_starlette_instrumentation.py | 8 ++++++++ .../instrumentation/wsgi/__init__.py | 2 ++ 8 files changed, 77 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b92f0c62c7..7100623987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Breaking changes + +- `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette` Use `tracer` and `meter` of originating components instead of one from `asgi` middleware + ([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580)) + ### Fixed - `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 8edb3420b1..e416e8dec2 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -461,6 +461,8 @@ class OpenTelemetryMiddleware: scope and event which are sent as dictionaries for when the method send is called. tracer_provider: The optional tracer provider to use. If omitted the current globally configured one is used. + meter_provider: The optional meter provider to use. If omitted + the current globally configured one is used. """ # pylint: disable=too-many-branches @@ -474,17 +476,22 @@ def __init__( client_response_hook: ClientResponseHook = None, tracer_provider=None, meter_provider=None, + tracer=None, meter=None, http_capture_headers_server_request: list[str] | None = None, http_capture_headers_server_response: list[str] | None = None, http_capture_headers_sanitize_fields: list[str] | None = None, ): self.app = guarantee_single_callable(app) - self.tracer = trace.get_tracer( - __name__, - __version__, - tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + self.tracer = ( + trace.get_tracer( + __name__, + __version__, + tracer_provider, + schema_url="https://opentelemetry.io/schemas/1.11.0", + ) + if tracer is None + else tracer ) self.meter = ( get_meter( diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index 902cd4ec7e..d2fe6bc52b 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -309,6 +309,10 @@ def validate_outputs(self, outputs, error=None, modifiers=None): self.assertEqual(span.name, expected["name"]) self.assertEqual(span.kind, expected["kind"]) self.assertDictEqual(dict(span.attributes), expected["attributes"]) + self.assertEqual( + span.instrumentation_scope.name, + "opentelemetry.instrumentation.asgi", + ) def test_basic_asgi_call(self): """Test that spans are emitted as expected.""" @@ -728,6 +732,10 @@ def test_asgi_metrics(self): self.assertTrue(len(resource_metric.scope_metrics) != 0) for scope_metric in resource_metric.scope_metrics: self.assertTrue(len(scope_metric.metrics) != 0) + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.asgi", + ) for metric in scope_metric.metrics: self.assertIn(metric.name, _expected_metric_names) data_points = list(metric.data.data_points) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 6f52c6ef3b..263cc0fb78 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -188,6 +188,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.metrics import get_meter from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.trace import get_tracer from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls _excluded_urls_from_env = get_excluded_urls("FASTAPI") @@ -221,6 +222,12 @@ def instrument_app( excluded_urls = _excluded_urls_from_env else: excluded_urls = parse_excluded_urls(excluded_urls) + tracer = get_tracer( + __name__, + __version__, + tracer_provider, + schema_url="https://opentelemetry.io/schemas/1.11.0", + ) meter = get_meter( __name__, __version__, @@ -235,7 +242,8 @@ def instrument_app( server_request_hook=server_request_hook, client_request_hook=client_request_hook, client_response_hook=client_response_hook, - tracer_provider=tracer_provider, + # Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation + tracer=tracer, meter=meter, ) app._is_instrumented_by_opentelemetry = True @@ -298,6 +306,12 @@ class _InstrumentedFastAPI(fastapi.FastAPI): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + tracer = get_tracer( + __name__, + __version__, + _InstrumentedFastAPI._tracer_provider, + schema_url="https://opentelemetry.io/schemas/1.11.0", + ) meter = get_meter( __name__, __version__, @@ -311,7 +325,8 @@ def __init__(self, *args, **kwargs): server_request_hook=_InstrumentedFastAPI._server_request_hook, client_request_hook=_InstrumentedFastAPI._client_request_hook, client_response_hook=_InstrumentedFastAPI._client_response_hook, - tracer_provider=_InstrumentedFastAPI._tracer_provider, + # Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation + tracer=tracer, meter=meter, ) self._is_instrumented_by_opentelemetry = True diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 5cf9a0d590..948bd343db 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -117,6 +117,10 @@ def test_instrument_app_with_instrument(self): self.assertEqual(len(spans), 3) for span in spans: self.assertIn("GET /foobar", span.name) + self.assertEqual( + span.instrumentation_scope.name, + "opentelemetry.instrumentation.fastapi", + ) def test_uninstrument_app(self): self._client.get("/foobar") @@ -197,6 +201,10 @@ def test_fastapi_metrics(self): for resource_metric in metrics_list.resource_metrics: self.assertTrue(len(resource_metric.scope_metrics) == 1) for scope_metric in resource_metric.scope_metrics: + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.fastapi", + ) self.assertTrue(len(scope_metric.metrics) == 3) for metric in scope_metric.metrics: self.assertIn(metric.name, _expected_metric_names) diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index 83f5b5c52b..4bb3608935 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -185,6 +185,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry.instrumentation.starlette.version import __version__ from opentelemetry.metrics import get_meter from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.trace import get_tracer from opentelemetry.util.http import get_excluded_urls _excluded_urls = get_excluded_urls("STARLETTE") @@ -208,6 +209,12 @@ def instrument_app( tracer_provider=None, ): """Instrument an uninstrumented Starlette application.""" + tracer = get_tracer( + __name__, + __version__, + tracer_provider, + schema_url="https://opentelemetry.io/schemas/1.11.0", + ) meter = get_meter( __name__, __version__, @@ -222,7 +229,8 @@ def instrument_app( server_request_hook=server_request_hook, client_request_hook=client_request_hook, client_response_hook=client_response_hook, - tracer_provider=tracer_provider, + # Pass in tracer/meter to get __name__and __version__ of starlette instrumentation + tracer=tracer, meter=meter, ) app.is_instrumented_by_opentelemetry = True @@ -278,6 +286,12 @@ class _InstrumentedStarlette(applications.Starlette): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + tracer = get_tracer( + __name__, + __version__, + _InstrumentedStarlette._tracer_provider, + schema_url="https://opentelemetry.io/schemas/1.11.0", + ) meter = get_meter( __name__, __version__, @@ -291,7 +305,8 @@ def __init__(self, *args, **kwargs): server_request_hook=_InstrumentedStarlette._server_request_hook, client_request_hook=_InstrumentedStarlette._client_request_hook, client_response_hook=_InstrumentedStarlette._client_response_hook, - tracer_provider=_InstrumentedStarlette._tracer_provider, + # Pass in tracer/meter to get __name__and __version__ of starlette instrumentation + tracer=tracer, meter=meter, ) self._is_instrumented_by_opentelemetry = True diff --git a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py index 0accda18fd..1e768982b5 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -98,6 +98,10 @@ def test_basic_starlette_call(self): self.assertEqual(len(spans), 3) for span in spans: self.assertIn("GET /foobar", span.name) + self.assertEqual( + span.instrumentation_scope.name, + "opentelemetry.instrumentation.starlette", + ) def test_starlette_route_attribute_added(self): """Ensure that starlette routes are used as the span name.""" @@ -132,6 +136,10 @@ def test_starlette_metrics(self): for resource_metric in metrics_list.resource_metrics: self.assertTrue(len(resource_metric.scope_metrics) == 1) for scope_metric in resource_metric.scope_metrics: + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.starlette", + ) self.assertTrue(len(scope_metric.metrics) == 3) for metric in scope_metric.metrics: self.assertIn(metric.name, _expected_metric_names) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 0a873d0fc3..810a07e315 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -533,6 +533,8 @@ class OpenTelemetryMiddleware: incoming request. tracer_provider: Optional tracer provider to use. If omitted the current globally configured one is used. + meter_provider: Optional meter provider to use. If omitted the current + globally configured one is used. """ def __init__( From bc4b0493b9d72c508ef172b61e14cc7f44c9d73b Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 7 Jun 2024 17:53:22 +0200 Subject: [PATCH 031/335] requirements: bump pytest to 7.4.4 (#2587) --- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-2.txt | 8 +++----- .../test-requirements-3.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-2.txt | 8 +++----- .../test-requirements-3.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-2.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-2.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-2.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements-2.txt | 8 +++----- .../test-requirements-3.txt | 8 +++----- .../test-requirements-4.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements-0.txt | 8 +++----- .../test-requirements-1.txt | 8 +++----- .../test-requirements.txt | 8 +++----- opentelemetry-distro/test-requirements.txt | 8 +++----- opentelemetry-instrumentation/test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../test-requirements.txt | 8 +++----- .../opentelemetry-sdk-extension-aws/test-requirements.txt | 8 +++----- 78 files changed, 234 insertions(+), 390 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 40c4886fd7..7676ce644d 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 charset-normalizer==3.3.2 cramjam==2.8.1 @@ -7,12 +6,11 @@ Deprecated==1.2.14 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==4.25.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-snappy==0.7.1 requests==2.31.0 diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index 42d2ec7b4c..af50fa87e8 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -1,17 +1,15 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 flaky==3.7.0 importlib-metadata==6.11.0 iniconfig==2.0.0 markdown-it-py==3.0.0 mdurl==0.1.2 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 Pygments==2.17.2 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 rich==13.7.1 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index c8ffea4e89..2935a1c7e0 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -1,18 +1,16 @@ aio-pika==7.2.0 aiormq==6.2.3 asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 -packaging==23.2 +packaging==24.0 pamqp==3.1.0 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index 1e2ea5a1e5..2db29de3ea 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -1,18 +1,16 @@ aio-pika==8.3.0 aiormq==6.6.4 asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 -packaging==23.2 +packaging==24.0 pamqp==3.2.1 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 7e1aa15fa0..536646e287 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -1,18 +1,16 @@ aio-pika==9.0.5 aiormq==6.7.1 asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 -packaging==23.2 +packaging==24.0 pamqp==3.2.1 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index 65c2ff8f0c..12168d97b1 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -1,18 +1,16 @@ aio-pika==9.4.1 aiormq==6.8.0 asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 -packaging==23.2 +packaging==24.0 pamqp==3.3.0 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index b8ccfd2a50..0209ca3dd6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -2,7 +2,6 @@ aiohttp==3.9.3 aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 -attrs==23.2.0 blinker==1.7.0 certifi==2024.2.2 charset-normalizer==3.3.2 @@ -18,11 +17,10 @@ itsdangerous==2.1.2 Jinja2==3.1.3 MarkupSafe==2.1.5 multidict==6.0.5 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.31.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index 9f6d7accce..16529b6db1 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -2,18 +2,16 @@ aiohttp==3.9.3 aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 -attrs==23.2.0 Deprecated==1.2.14 frozenlist==1.4.1 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-aiohttp==1.0.5 pytest-asyncio==0.23.5 pytest-benchmark==4.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 2b03677f42..033cee4492 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -1,17 +1,15 @@ aiopg==1.4.0 asgiref==3.7.2 async-timeout==4.0.3 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 install==1.3.5 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 psycopg2-binary==2.9.9 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index f3ee9764cf..9411be3b90 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index 14f724888b..4943fcc851 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-asyncio==0.23.5 pytest-benchmark==4.0.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index 02d8fb2041..2ef86b3d94 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 async-timeout==4.0.3 asyncpg==0.29.0 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index 53e5b9ce6f..b5168dc7fe 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 4f8c5d2b67..8d6d6692ce 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 boto==2.49.0 boto3==1.34.44 botocore==1.34.44 @@ -16,12 +15,11 @@ Jinja2==3.1.4 jmespath==1.0.1 MarkupSafe==2.1.5 moto==2.3.2 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pycparser==2.21 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index 2af3346e6d..8ddfd9983f 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -1,16 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 boto3==1.34.44 botocore==1.34.44 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 jmespath==1.0.1 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 s3transfer==0.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index 7229f0f721..b3fa765d5c 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 aws-xray-sdk==2.12.1 boto3==1.28.80 botocore==1.31.80 @@ -16,12 +15,11 @@ Jinja2==3.1.4 jmespath==1.0.1 MarkupSafe==2.0.1 moto==3.1.19 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pycparser==2.21 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index f55190171d..f0d811982b 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -1,16 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 cassandra-driver==3.29.0 click==8.1.7 Deprecated==1.2.14 geomet==0.2.1.post1 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 PyYAML==6.0.1 scylla-driver==3.26.6 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index 98c661ca67..3159fefaf8 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -1,6 +1,5 @@ amqp==5.2.0 asgiref==3.7.2 -attrs==23.2.0 backports.zoneinfo==0.2.1 billiard==4.2.0 celery==5.3.6 @@ -12,12 +11,11 @@ Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 kombu==5.3.5 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 prompt-toolkit==3.0.43 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 516e1a78b9..6012f89379 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -1,6 +1,5 @@ amqp==5.2.0 asgiref==3.7.2 -attrs==23.2.0 billiard==4.2.0 celery==5.3.6 click==8.1.7 @@ -11,12 +10,11 @@ Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 kombu==5.3.5 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 prompt-toolkit==3.0.43 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index be859a2ce1..1297185d4b 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 confluent-kafka==2.3.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index 46c02707c1..d35a55f831 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index 6dce957000..2203da3e33 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 Django==2.2.28 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 pytz==2024.1 sqlparse==0.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index 548db1b8e3..bf7239cce6 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 Django==3.2.25 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 pytz==2024.1 sqlparse==0.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 0970d2f253..03d4570977 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 backports.zoneinfo==0.2.1 Deprecated==1.2.14 Django==4.2.11 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 sqlparse==0.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index d853c05877..ec200f92ef 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 Django==4.2.11 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 sqlparse==0.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index 054c8a8047..dac65a0f01 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 elasticsearch==6.8.2 elasticsearch-dsl==6.4.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index efa05fd7ff..c9baa38ad6 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 elasticsearch==7.17.9 elasticsearch-dsl==7.4.1 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index 6b0d677ec7..b852eff7cb 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -1,16 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 elasticsearch==8.13.1 elasticsearch-dsl==8.13.1 elastic-transport==8.13.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index 31c7f1d7c8..f17ada63f4 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 falcon==1.4.1 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-mimeparse==1.6.0 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index ad476d7c22..68b1aba13d 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 falcon==2.0.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index 6c5c3e8ac9..4b4f8e7c0d 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 falcon==3.1.1 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 8d7bf3ad78..44547cb0ea 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -1,7 +1,6 @@ annotated-types==0.6.0 anyio==4.3.0 asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 charset-normalizer==3.3.2 Deprecated==1.2.14 @@ -13,13 +12,12 @@ httpx==0.27.0 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pydantic==2.6.2 pydantic_core==2.16.3 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.31.0 sniffio==1.3.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index fbefeebdb4..fcedc7c695 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 click==8.1.7 Deprecated==1.2.14 Flask==2.1.3 @@ -8,11 +7,10 @@ iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.3 MarkupSafe==2.1.2 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index 41583ad7f9..c6773ad2e9 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 click==8.1.7 Deprecated==1.2.14 Flask==2.2.0 @@ -8,11 +7,10 @@ iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.3 MarkupSafe==2.1.2 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 3a89328861..3c7be28971 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 blinker==1.7.0 click==8.1.7 Deprecated==1.2.14 @@ -9,11 +8,10 @@ iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.3 MarkupSafe==2.1.2 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt index 9303dc27c0..d30aa5c5e9 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 grpcio==1.62.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index 2d3a8399d8..ad9e297219 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -1,6 +1,5 @@ anyio==3.7.1 asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 Deprecated==1.2.14 exceptiongroup==1.2.0 @@ -10,11 +9,10 @@ httpx==0.18.2 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 respx==0.17.1 rfc3986==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index 4a36398fc1..d1526ef5c1 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -1,6 +1,5 @@ anyio==4.3.0 asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 Deprecated==1.2.14 exceptiongroup==1.2.0 @@ -10,11 +9,10 @@ httpx==0.27.0 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 respx==0.20.2 sniffio==1.3.1 diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index d8ab59ac2d..6461129bee 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.3 MarkupSafe==2.0.1 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index 96bef86dbe..2f7007f872 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 kafka-python==2.0.2 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index f376796169..b7fcdc3dee 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt index f113b768b1..95cd6ab35f 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 mysql-connector-python==8.3.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index afa2ccae6c..78060fbccc 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 mysqlclient==2.2.4 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index fb3c6def5a..b6aa239e0f 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 +packaging==24.0 pika==0.13.1 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index d3ce673dab..334d08f537 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 +packaging==24.0 pika==1.3.2 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index 4b57cb1ca5..d9e9b4de0b 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 backports.zoneinfo==0.2.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 psycopg==3.1.18 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index d449374047..9269a3c378 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 psycopg==3.1.18 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index ade3b5fd26..28ad25715d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 psycopg2==2.9.9 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index 2e7313ab6e..ddb06914f7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==1.3.5 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index a1a3cc4fb1..a6ad4d0248 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==2.2.2 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index cb28ea22d7..7405224a8d 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==3.4.1 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index 40152664ac..d817e70c59 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==3.4.2 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index 9031276ce4..606d79143c 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==4.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index 0ad6375a14..2fd3f4ed0e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 dnspython==2.6.1 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pymongo==4.6.3 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index cb6619c5de..9a1076a543 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 PyMySQL==1.1.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 1362e7166e..3edddf72c3 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -1,18 +1,16 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 hupper==1.12.1 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 +packaging==24.0 PasteDeploy==3.1.0 plaster==1.1.2 plaster-pastedeploy==1.0.1 -pluggy==1.4.0 -py==1.11.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pyramid==2.0.2 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 translationstring==1.4 diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 90617f72e6..00b0a04b3e 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 async-timeout==4.0.3 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 redis==5.0.1 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index c50dfde9b5..0f6374b7ef 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 prometheus_client==0.20.0 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index be34594506..7c56a9b3d1 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 charset-normalizer==3.3.2 Deprecated==1.2.14 @@ -7,11 +6,10 @@ httpretty==1.1.4 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.31.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt index fc966b4d6a..885caae033 100644 --- a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt @@ -1,15 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 joblib==1.3.2 numpy==1.24.4 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 scikit-learn==0.24.2 scipy==1.10.1 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index 26fd283824..04f4fe0c4b 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -1,16 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 cffi==1.15.1 Deprecated==1.2.14 greenlet==0.4.13 hpy==0.0.4.dev179+g9b5d200 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 readline==6.2.4.1 SQLAlchemy==1.1.18 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index bfb9dac972..4e1620b772 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -1,15 +1,13 @@ aiosqlite==0.20.0 asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 greenlet==3.0.3 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 SQLAlchemy==1.4.51 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index 16cfb33801..848f207c8c 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 1cd21039a7..0cd1fb534a 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -1,6 +1,5 @@ anyio==4.3.0 asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 charset-normalizer==3.3.2 Deprecated==1.2.14 @@ -11,11 +10,10 @@ httpx==0.27.0 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.31.0 sniffio==1.3.0 diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index ee56025d5f..ddb98399cf 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 psutil==5.9.8 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index 4f9b027918..eb37259669 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 9f637278fd..0d22bceff5 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -attrs==23.2.0 blinker==1.7.0 certifi==2024.2.2 charset-normalizer==3.3.2 @@ -13,11 +12,10 @@ iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.3 MarkupSafe==2.1.5 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.31.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index 0fafc56253..2d518c1192 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -1,19 +1,17 @@ aiosqlite==0.17.0 annotated-types==0.6.0 asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 iso8601==1.1.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 pydantic==2.6.2 pydantic_core==2.16.3 pypika-tortoise==0.1.6 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 pytz==2024.1 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index cdb10df7e9..0ac7842086 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 httpretty==1.1.4 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index 730ef16977..05a76b1bcb 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 httpretty==1.1.4 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 1f10502f57..9c6d596068 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -1,14 +1,12 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 httpretty==1.1.4 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index a4910352ed..a25f8882d1 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index 978389dc9a..b93758ee31 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index 473a423bda..2ef62218b1 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index b6b197bdcc..a6249b4a87 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -1,16 +1,14 @@ asgiref==3.7.2 -attrs==23.2.0 certifi==2024.2.2 charset-normalizer==3.3.2 Deprecated==1.2.14 idna==3.6 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.31.0 tomli==2.0.1 diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index 69c1829a5c..59c30eabf4 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/resource/opentelemetry-resource-detector-container/test-requirements.txt b/resource/opentelemetry-resource-detector-container/test-requirements.txt index eee7aaa46d..ecacb62b12 100644 --- a/resource/opentelemetry-resource-detector-container/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-container/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt index e569ade322..4ed081e748 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt @@ -1,13 +1,11 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 -py==1.11.0 +packaging==24.0 +pluggy==1.5.0 py-cpuinfo==9.0.0 -pytest==7.1.3 +pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 From 0216a9644af00efe99311ff2380a6adf4f244a84 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 7 Jun 2024 18:14:21 +0200 Subject: [PATCH 032/335] CONTRIBUTING: Make it more explicit you need to sign the CLA (#2582) --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 743449c2a7..b3ae4cbfed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,10 @@ on how to become a [**Member**](https://github.com/open-telemetry/community/blob [**Approver**](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) and [**Maintainer**](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer). +Before you can contribute, you will need to sign the [Contributor License Agreement](https://docs.linuxfoundation.org/lfx/easycla/contributors). + +Please also read the [OpenTelemetry Contributor Guide](https://github.com/open-telemetry/community/blob/main/CONTRIBUTING.md). + ## Index * [Find a Buddy and get Started Quickly](#find-a-buddy-and-get-started-quickly) From 3511ed180d568fa180420b9fc4968cd8c70a94c7 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 7 Jun 2024 21:54:38 +0200 Subject: [PATCH 033/335] requirements: Bump idna to 3.7 (#2583) --- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-fastapi/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-httpx/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-httpx/test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index 2935a1c7e0..3744af85b1 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -2,7 +2,7 @@ aio-pika==7.2.0 aiormq==6.2.3 asgiref==3.7.2 Deprecated==1.2.14 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index 2db29de3ea..bb35e2e2ba 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -2,7 +2,7 @@ aio-pika==8.3.0 aiormq==6.6.4 asgiref==3.7.2 Deprecated==1.2.14 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 536646e287..3b17c80c25 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -2,7 +2,7 @@ aio-pika==9.0.5 aiormq==6.7.1 asgiref==3.7.2 Deprecated==1.2.14 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index 12168d97b1..4ea66f8dd6 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -2,7 +2,7 @@ aio-pika==9.4.1 aiormq==6.8.0 asgiref==3.7.2 Deprecated==1.2.14 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 0209ca3dd6..75128c7c42 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -10,7 +10,7 @@ Deprecated==1.2.14 Flask==3.0.2 frozenlist==1.4.1 http_server_mock==1.7 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index 16529b6db1..c62da59804 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -4,7 +4,7 @@ asgiref==3.7.2 async-timeout==4.0.3 Deprecated==1.2.14 frozenlist==1.4.1 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 8d6d6692ce..59d9c37010 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -8,7 +8,7 @@ charset-normalizer==3.3.2 cryptography==42.0.3 Deprecated==1.2.14 docker==7.0.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index b3fa765d5c..29c6c90230 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -8,7 +8,7 @@ charset-normalizer==3.3.2 cryptography==42.0.5 Deprecated==1.2.14 docker==7.0.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 44547cb0ea..3806570105 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -9,7 +9,7 @@ fastapi==0.109.2 h11==0.14.0 httpcore==1.0.4 httpx==0.27.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index ad9e297219..ca3a0908fa 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -6,7 +6,7 @@ exceptiongroup==1.2.0 h11==0.12.0 httpcore==0.13.7 httpx==0.18.2 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index d1526ef5c1..d3476cea4b 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -6,7 +6,7 @@ exceptiongroup==1.2.0 h11==0.14.0 httpcore==1.0.4 httpx==0.27.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 7c56a9b3d1..16458d96d4 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -3,7 +3,7 @@ certifi==2024.2.2 charset-normalizer==3.3.2 Deprecated==1.2.14 httpretty==1.1.4 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 0cd1fb534a..53f85db350 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -7,7 +7,7 @@ exceptiongroup==1.2.0 h11==0.14.0 httpcore==1.0.4 httpx==0.27.0 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 0d22bceff5..db4e7ba7d1 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -6,7 +6,7 @@ click==8.1.7 Deprecated==1.2.14 Flask==3.0.2 http_server_mock==1.7 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 From 4357c35dd253e9def9a113affab64b30777bcd6c Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 10 Jun 2024 17:59:40 +0200 Subject: [PATCH 034/335] requirements: missed pytest and idna bumps (#2592) --- dev-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index be65b731c7..60db203e2d 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,7 +7,7 @@ mypy==0.931 sphinx==7.1.2 sphinx-rtd-theme==2.0.0rc4 sphinx-autodoc-typehints==1.25.2 -pytest==7.1.3 +pytest==7.4.4 pytest-cov==4.1.0 readme-renderer==42.0 bleach==4.1.0 # transient dependency for readme-renderer diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 7676ce644d..7c3ab4d83e 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -3,7 +3,7 @@ certifi==2024.2.2 charset-normalizer==3.3.2 cramjam==2.8.1 Deprecated==1.2.14 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index a6249b4a87..bbe805e794 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.7.2 certifi==2024.2.2 charset-normalizer==3.3.2 Deprecated==1.2.14 -idna==3.6 +idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 From 97621523b80ebebe5142d4c94f129e056c3b3e29 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 10 Jun 2024 18:08:14 +0200 Subject: [PATCH 035/335] requirements: bump Werkzeug (#2594) --- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 75128c7c42..f02ffb216f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -26,7 +26,7 @@ requests==2.31.0 tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.1 -Werkzeug==3.0.1 +Werkzeug==3.0.3 wrapt==1.16.0 yarl==1.9.4 zipp==3.17.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 59d9c37010..9f3bbd7508 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -31,7 +31,7 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 urllib3==1.26.18 -Werkzeug==2.1.2 +Werkzeug==2.3.8 wrapt==1.16.0 xmltodict==0.13.0 zipp==3.17.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 3c7be28971..98638a4ed6 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -15,7 +15,7 @@ pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 -Werkzeug==3.0.1 +Werkzeug==3.0.3 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index db4e7ba7d1..121fdacf3c 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -22,7 +22,7 @@ tomli==2.0.1 tornado==6.4 typing_extensions==4.9.0 urllib3==2.2.1 -Werkzeug==3.0.1 +Werkzeug==3.0.3 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation From ab0ea0e0f9b96d9ef0d921a527c5affb0b434420 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 10 Jun 2024 21:49:10 +0200 Subject: [PATCH 036/335] Add support for python 3.12 (#2572) --- .github/workflows/instrumentations_0.yml | 9 +- .github/workflows/instrumentations_1.yml | 5 +- .github/workflows/lint.yml | 6 +- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 5 +- CONTRIBUTING.md | 2 +- _template/pyproject.toml | 1 + .../pyproject.toml | 2 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 3 +- .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 4 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 4 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 3 - .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + opentelemetry-distro/pyproject.toml | 4 + opentelemetry-instrumentation/pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + tox.ini | 122 +++++++++--------- util/opentelemetry-util-http/pyproject.toml | 1 + 66 files changed, 149 insertions(+), 75 deletions(-) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index 5fb21ad672..fb8df0dcbb 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -16,13 +16,14 @@ jobs: py39: 3.9 py310: "3.10" py311: "3.11" + py312: "3.12" pypy3: pypy-3.8 RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - python-version: [py38, py39, py310, py311, pypy3] + python-version: [py38, py39, py310, py311, py312, pypy3] package: # Do not add more instrumentations here, add them in instrumentations_1.yml. # The reason for this separation of instrumentations into more than one YAML file is @@ -80,6 +81,12 @@ jobs: package: "sklearn" - python-version: py311 package: "sklearn" + - python-version: py312 + package: "sklearn" + - python-version: py312 + package: "boto" + - python-version: py312 + package: "kafka-python" - python-version: pypy3 package: "aiopg" - python-version: pypy3 diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 2bab23d7d2..7783105cd1 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -16,13 +16,14 @@ jobs: py39: 3.9 py310: "3.10" py311: "3.11" + py312: "3.12" pypy3: pypy-3.8 RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - python-version: [py38, py39, py310, py311, pypy3] + python-version: [py38, py39, py310, py311, py312, pypy3] package: - "urllib" - "urllib3" @@ -37,8 +38,6 @@ jobs: - "resource-detector-container" os: [ubuntu-20.04] exclude: - - python-version: py311 - package: "prometheus-remote-write" - python-version: pypy3 package: "prometheus-remote-write" steps: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 859b567824..debecc6ff8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,7 +9,7 @@ env: CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e jobs: - lint-3_11: + lint-3_12: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: @@ -75,10 +75,10 @@ jobs: steps: - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: 3.12 - name: Install tox run: pip install tox - name: Cache tox environment diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbdffe129b..b01b7ce4d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: rev: 24.3.0 hooks: - id: black - language_version: python3.11 + language_version: python3.12 - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7100623987..e17542b104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) +- Add Python 3.12 support + ([#2572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2572)) ## Version 1.25.0/0.46b0 (2024-05-31) @@ -47,7 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2253](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2253)) - `opentelemetry-instrumentation-pika` Instrumentation for `channel.consume()` (supported only for global, non channel specific instrumentation) - ([#2397](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2397))) + ([#2397](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2397)) - `opentelemetry-processor-baggage` Initial release ([#2436](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2436)) - `opentelemetry-processor-baggage` Add baggage key predicate @@ -129,6 +131,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Version 1.22.0/0.43b0 (2023-12-14) ### Added + - `opentelemetry-instrumentation-asyncio` Add support for asyncio ([#1919](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1943)) - `opentelemetry-instrumentation` Added Otel semantic convention opt-in mechanism diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b3ae4cbfed..2cd72f12d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,7 +63,7 @@ You can run `tox` with the following arguments: - `tox` to run all existing tox commands, including unit tests for all packages under multiple Python versions - `tox -e docs` to regenerate the API docs -- `tox -e py311-test-instrumentation-aiopg` to e.g. run the aiopg instrumentation unit tests under a specific +- `tox -e py312-test-instrumentation-aiopg` to e.g. run the aiopg instrumentation unit tests under a specific Python version - `tox -e spellcheck` to run a spellcheck on all the code - `tox -e lint-some-package` to run lint checks on `some-package` diff --git a/_template/pyproject.toml b/_template/pyproject.toml index ca3da89a30..514b537f42 100644 --- a/_template/pyproject.toml +++ b/_template/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml index b0006a0682..4218e13472 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml @@ -22,6 +22,8 @@ classifiers = [ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "protobuf ~= 4.21", diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index aa672ac84d..745a3bc25d 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 71956d28ce..3907320999 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.5", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index 4eb0b25b17..f8b4750872 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index a335800216..cd5516c8f6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -21,7 +21,8 @@ classifiers = [ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11" + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 17d4513dc9..e9e7f7f613 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 3e7fc8b9c9..d733700a15 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "asgiref ~= 3.0", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index b6b272a57a..2a53899ecd 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.14", diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 9f4f9edd8a..f5d4ffd1f6 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index 8e559db99b..cbed1edb9e 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -19,6 +19,10 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-instrumentation == 0.47b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 295204abb8..e8a2196483 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 7749163b51..6c92273301 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 7c55c88b8f..17596cee98 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index e4b734c0f7..72808bbda7 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 13e7ca94cd..cac767986e 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -19,6 +19,10 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-instrumentation == 0.47b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index cf8b2d5dd2..6a81203f01 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index 74a9b10a59..e1f67c283d 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index b16f79f2ca..d6e8408738 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 14e92041fa..5e0bcdad19 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index c8cff0d46d..7bae75494e 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index f0abd0dc04..1b769d2957 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index 6acda1ff8b..d43c5ed173 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 8e94e70de8..de890755dc 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index a93fe78d7e..78417289df 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index df254c9d60..658d4eac3c 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 1c66bb932c..58982a6781 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index bb4f62975a..c36f0e1c55 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 011bee252c..8cff4d3d24 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-instrumentation == 0.47b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 8790a02026..81baee5267 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index ebc3ed592a..581ff20229 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 46ce5870a7..eab52fa474 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index bc921d0dd5..d77e95b90e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 39eb241054..bc06e31b86 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 221e74a602..96edbff3b2 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 0139ba5fb8..af342aa076 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 5b4d838d56..d3c1bd345d 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index b3a56b7976..504634007c 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml index 22fb150cf8..6e57529ed1 100644 --- a/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml @@ -19,9 +19,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index ee602ead86..c9a54920a2 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index ddc1eb1fab..09f302e64e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index bf087d64d2..9103dd6f2a 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 6847372597..07ba2faa20 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-instrumentation == 0.47b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 418bf5e537..d496b99f7a 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index 345d226a55..ab5d522aa2 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -21,6 +21,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 1d5d30aa45..dc0293d3d5 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index cc1594a31e..90799c4492 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index e4a6892b23..b9dd6d528f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index 32766c2def..e56e4e9eb9 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index ff100a1ca6..74c28f38cf 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-instrumentation-aio-pika==0.47b0.dev", diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index cf6b3a671b..17f8e5de43 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -19,6 +19,10 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Typing :: Typed", ] dependencies = [ diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index a20b005911..edaf400419 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.4", diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 0ef5392fdb..3fa80e1517 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.5", diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 6361de39a0..69fd0bbbfa 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml index 41f374ee1b..93c7ad6784 100644 --- a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml +++ b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index efa1b24ee7..f86f1f097b 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-sdk ~= 1.21", diff --git a/resource/opentelemetry-resource-detector-container/pyproject.toml b/resource/opentelemetry-resource-detector-container/pyproject.toml index 4ad1df12cd..3993ecd06c 100644 --- a/resource/opentelemetry-resource-detector-container/pyproject.toml +++ b/resource/opentelemetry-resource-detector-container/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-sdk ~= 1.12", diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml index 12b2b23ddc..767bebdd10 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml +++ b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-sdk ~= 1.12", diff --git a/tox.ini b/tox.ini index 63c80083d4..e0d5d79cbc 100644 --- a/tox.ini +++ b/tox.ini @@ -7,53 +7,53 @@ envlist = ; for specifying supported Python versions per package. ; opentelemetry-resource-detector-container - py3{8,9,10,11}-test-resource-detector-container + py3{8,9,10,11,12}-test-resource-detector-container pypy3-test-resource-detector-container lint-resource-detector-container ; opentelemetry-sdk-extension-aws - py3{8,9,10,11}-test-sdk-extension-aws + py3{8,9,10,11,12}-test-sdk-extension-aws pypy3-test-sdk-extension-aws lint-sdk-extension-aws ; opentelemetry-distro - py3{8,9,10,11}-test-distro + py3{8,9,10,11,12}-test-distro pypy3-test-distro lint-distro ; opentelemetry-instrumentation - py3{8,9,10,11}-test-opentelemetry-instrumentation + py3{8,9,10,11,12}-test-opentelemetry-instrumentation pypy3-test-opentelemetry-instrumentation lint-opentelemetry-instrumentation ; opentelemetry-instrumentation-aiohttp-client - py3{8,9,10,11}-test-instrumentation-aiohttp-client + py3{8,9,10,11,12}-test-instrumentation-aiohttp-client pypy3-test-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client ; opentelemetry-instrumentation-aiohttp-server - py3{8,9,10,11}-test-instrumentation-aiohttp-server + py3{8,9,10,11,12}-test-instrumentation-aiohttp-server pypy3-test-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server ; opentelemetry-instrumentation-aiopg - py3{8,9,10,11}-test-instrumentation-aiopg + py3{8,9,10,11,12}-test-instrumentation-aiopg ; instrumentation-aiopg intentionally excluded from pypy3 lint-instrumentation-aiopg ; opentelemetry-instrumentation-aws-lambda - py3{8,9,10,11}-test-instrumentation-aws-lambda + py3{8,9,10,11,12}-test-instrumentation-aws-lambda pypy3-test-instrumentation-aws-lambda lint-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{8,9,10,11}-test-instrumentation-botocore + py3{8,9,10,11,12}-test-instrumentation-botocore ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore ; opentelemetry-instrumentation-boto3sqs - py3{8,9,10,11}-test-instrumentation-boto3sqs + py3{8,9,10,11,12}-test-instrumentation-boto3sqs pypy3-test-instrumentation-boto3sqs lint-instrumentation-boto3sqs @@ -70,13 +70,13 @@ envlist = py3{8,9}-test-instrumentation-django-0 py3{8,9}-test-instrumentation-django-1 py3{8,9}-test-instrumentation-django-2 - py3{10,11}-test-instrumentation-django-1 - py3{10,11}-test-instrumentation-django-3 + py3{10,11,12}-test-instrumentation-django-1 + py3{10,11,12}-test-instrumentation-django-3 pypy3-test-instrumentation-django-{0,1} lint-instrumentation-django ; opentelemetry-instrumentation-dbapi - py3{8,9,10,11}-test-instrumentation-dbapi + py3{8,9,10,11,12}-test-instrumentation-dbapi pypy3-test-instrumentation-dbapi lint-instrumentation-dbapi @@ -92,7 +92,7 @@ envlist = ; 0: elasticsearch-dsl==6.4.0 elasticsearch==6.8.2 ; 1: elasticsearch-dsl==7.4.1 elasticsearch==7.17.9 ; 2: elasticsearch-dsl==8.13.1 elasticsearch==8.13.1 - py3{8,9,10,11}-test-instrumentation-elasticsearch-{0,1,2} + py3{8,9,10,11,12}-test-instrumentation-elasticsearch-{0,1,2} pypy3-test-instrumentation-elasticsearch-{0,1,2} lint-instrumentation-elasticsearch @@ -104,12 +104,12 @@ envlist = ; 1: falcon >=2.0.0,<3.0.0 ; 2: falcon >=3.0.0,<4.0.0 py3{8,9}-test-instrumentation-falcon-0 - py3{8,9,10,11}-test-instrumentation-falcon-{1,2} + py3{8,9,10,11,12}-test-instrumentation-falcon-{1,2} pypy3-test-instrumentation-falcon-{0,1,2} lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi - py3{8,9,10,11}-test-instrumentation-fastapi + py3{8,9,10,11,12}-test-instrumentation-fastapi pypy3-test-instrumentation-fastapi lint-instrumentation-fastapi @@ -119,13 +119,13 @@ envlist = ; 0: Flask ==2.1.3 Werkzeug <3.0.0 ; 1: Flask ==2.2.0 Werkzeug <3.0.0 ; 2: Flask >=3.0.0 Werkzeug >=3.0.0 - py3{8,9,10,11}-test-instrumentation-flask-{0,1} - py3{8,9,10,11}-test-instrumentation-flask-{2} + py3{8,9,10,11,12}-test-instrumentation-flask-{0,1} + py3{8,9,10,11,12}-test-instrumentation-flask-{2} pypy3-test-instrumentation-flask-{0,1} lint-instrumentation-flask ; opentelemetry-instrumentation-urllib - py3{8,9,10,11}-test-instrumentation-urllib + py3{8,9,10,11,12}-test-instrumentation-urllib pypy3-test-instrumentation-urllib lint-instrumentation-urllib @@ -134,47 +134,47 @@ envlist = ; below mean these dependencies are being used: ; 0: urllib3 >=1.0.0,<2.0.0 ; 1: urllib3 >=2.0.0,<3.0.0 - py3{8,9,10,11}-test-instrumentation-urllib3-{0,1} + py3{8,9,10,11,12}-test-instrumentation-urllib3-{0,1} pypy3-test-instrumentation-urllib3-{0,1} lint-instrumentation-urllib3 ; opentelemetry-instrumentation-requests - py3{8,9,10,11}-test-instrumentation-requests + py3{8,9,10,11,12}-test-instrumentation-requests ;pypy3-test-instrumentation-requests lint-instrumentation-requests ; opentelemetry-instrumentation-starlette - py3{8,9,10,11}-test-instrumentation-starlette + py3{8,9,10,11,12}-test-instrumentation-starlette pypy3-test-instrumentation-starlette lint-instrumentation-starlette ; opentelemetry-instrumentation-jinja2 - py3{8,9,10,11}-test-instrumentation-jinja2 + py3{8,9,10,11,12}-test-instrumentation-jinja2 pypy3-test-instrumentation-jinja2 lint-instrumentation-jinja2 ; opentelemetry-instrumentation-logging - py3{8,9,10,11}-test-instrumentation-logging + py3{8,9,10,11,12}-test-instrumentation-logging pypy3-test-instrumentation-logging lint-instrumentation-logging ; opentelemetry-exporter-richconsole - py3{8,9,10,11}-test-exporter-richconsole + py3{8,9,10,11,12}-test-exporter-richconsole pypy3-test-exporter-richconsole lint-exporter-richconsole ; opentelemetry-exporter-prometheus-remote-write - py3{8,9,10,11}-test-exporter-prometheus-remote-write + py3{8,9,10,11,12}-test-exporter-prometheus-remote-write pypy3-test-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write ; opentelemetry-instrumentation-mysql - py3{8,9,10,11}-test-instrumentation-mysql + py3{8,9,10,11,12}-test-instrumentation-mysql pypy3-test-instrumentation-mysql lint-instrumentation-mysql ; opentelemetry-instrumentation-mysqlclient - py3{8,9,10,11}-test-instrumentation-mysqlclient + py3{8,9,10,11,12}-test-instrumentation-mysqlclient pypy3-test-instrumentation-mysqlclient ; prerequisite: follow the instructions here ; https://github.com/PyMySQL/mysqlclient#install @@ -182,12 +182,12 @@ envlist = lint-instrumentation-mysqlclient ; opentelemetry-instrumentation-psycopg2 - py3{8,9,10,11}-test-instrumentation-psycopg2 + py3{8,9,10,11,12}-test-instrumentation-psycopg2 ; ext-psycopg2 intentionally excluded from pypy3 lint-instrumentation-psycopg2 ; opentelemetry-instrumentation-psycopg - py3{8,9,10,11}-test-instrumentation-psycopg + py3{8,9,10,11,12}-test-instrumentation-psycopg pypy3-test-instrumentation-psycopg lint-instrumentation-psycopg @@ -199,47 +199,47 @@ envlist = ; 2: pymemcache >3.0.0,<3.4.2 ; 3: pymemcache ==3.4.2 ; 4: pymemcache ==4.0.0 - py3{8,9,10,11}-test-instrumentation-pymemcache-{0,1,2,3,4} + py3{8,9,10,11,12}-test-instrumentation-pymemcache-{0,1,2,3,4} pypy3-test-instrumentation-pymemcache-{0,1,2,3,4} lint-instrumentation-pymemcache ; opentelemetry-instrumentation-pymongo - py3{8,9,10,11}-test-instrumentation-pymongo + py3{8,9,10,11,12}-test-instrumentation-pymongo pypy3-test-instrumentation-pymongo lint-instrumentation-pymongo ; opentelemetry-instrumentation-pymysql - py3{8,9,10,11}-test-instrumentation-pymysql + py3{8,9,10,11,12}-test-instrumentation-pymysql pypy3-test-instrumentation-pymysql lint-instrumentation-pymysql ; opentelemetry-instrumentation-pyramid - py3{8,9,10,11}-test-instrumentation-pyramid + py3{8,9,10,11,12}-test-instrumentation-pyramid pypy3-test-instrumentation-pyramid lint-instrumentation-pyramid ; opentelemetry-instrumentation-asgi - py3{8,9,10,11}-test-instrumentation-asgi + py3{8,9,10,11,12}-test-instrumentation-asgi pypy3-test-instrumentation-asgi lint-instrumentation-asgi ; opentelemetry-instrumentation-asyncpg - py3{8,9,10,11}-test-instrumentation-asyncpg + py3{8,9,10,11,12}-test-instrumentation-asyncpg ; ext-asyncpg intentionally excluded from pypy3 lint-instrumentation-asyncpg ; opentelemetry-instrumentation-sqlite3 - py3{8,9,10,11}-test-instrumentation-sqlite3 + py3{8,9,10,11,12}-test-instrumentation-sqlite3 pypy3-test-instrumentation-sqlite3 lint-instrumentation-sqlite3 ; opentelemetry-instrumentation-wsgi - py3{8,9,10,11}-test-instrumentation-wsgi + py3{8,9,10,11,12}-test-instrumentation-wsgi pypy3-test-instrumentation-wsgi lint-instrumentation-wsgi ; opentelemetry-instrumentation-grpc - py3{8,9,10,11}-test-instrumentation-grpc + py3{8,9,10,11,12}-test-instrumentation-grpc pypy3-test-instrumentation-grpc lint-instrumentation-grpc @@ -248,22 +248,22 @@ envlist = ; below mean these dependencies are being used: ; 0: sqlalchemy>=1.1,<1.2 ; 1: sqlalchemy~=1.4 aiosqlite - py3{8,9,10,11}-test-instrumentation-sqlalchemy-{1} + py3{8,9,10,11,12}-test-instrumentation-sqlalchemy-{1} pypy3-test-instrumentation-sqlalchemy-{0,1} lint-instrumentation-sqlalchemy ; opentelemetry-instrumentation-redis - py3{8,9,10,11}-test-instrumentation-redis + py3{8,9,10,11,12}-test-instrumentation-redis pypy3-test-instrumentation-redis lint-instrumentation-redis ; opentelemetry-instrumentation-remoulade - py3{8,9,10,11}-test-instrumentation-remoulade + py3{8,9,10,11,12}-test-instrumentation-remoulade ; instrumentation-remoulade intentionally excluded from pypy3 lint-instrumentation-remoulade ; opentelemetry-instrumentation-celery - py3{8,9,10,11}-test-instrumentation-celery + py3{8,9,10,11,12}-test-instrumentation-celery pypy3-test-instrumentation-celery lint-instrumentation-celery @@ -272,22 +272,22 @@ envlist = lint-instrumentation-sklearn ; opentelemetry-instrumentation-system-metrics - py3{8,9,10,11}-test-instrumentation-system-metrics + py3{8,9,10,11,12}-test-instrumentation-system-metrics pypy3-test-instrumentation-system-metrics lint-instrumentation-system-metrics ; opentelemetry-instrumentation-threading - py3{8,9,10,11}-test-instrumentation-threading + py3{8,9,10,11,12}-test-instrumentation-threading pypy3-test-instrumentation-threading lint-instrumentation-threading ; opentelemetry-instrumentation-tornado - py3{8,9,10,11}-test-instrumentation-tornado + py3{8,9,10,11,12}-test-instrumentation-tornado pypy3-test-instrumentation-tornado lint-instrumentation-tornado ; opentelemetry-instrumentation-tortoiseorm - py3{8,9,10,11}-test-instrumentation-tortoiseorm + py3{8,9,10,11,12}-test-instrumentation-tortoiseorm pypy3-test-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm @@ -296,21 +296,21 @@ envlist = ; below mean these dependencies are being used: ; 0: httpx>=0.18.0,<0.19.0 respx~=0.17.0 ; 1: httpx>=0.19.0 respx~=0.20.1 - py3{8,9,10,11}-test-instrumentation-httpx-{0,1} + py3{8,9,10,11,12}-test-instrumentation-httpx-{0,1} pypy3-test-instrumentation-httpx-{0,1} lint-instrumentation-httpx ; opentelemetry-util-http - py3{8,9,10,11}-test-util-http + py3{8,9,10,11,12}-test-util-http pypy3-test-util-http ; opentelemetry-propagator-aws-xray - py3{8,9,10,11}-test-propagator-aws-xray + py3{8,9,10,11,12}-test-propagator-aws-xray pypy3-test-propagator-aws-xray lint-propagator-aws-xray ; opentelemetry-propagator-ot-trace - py3{8,9,10,11}-test-propagator-ot-trace + py3{8,9,10,11,12}-test-propagator-ot-trace pypy3-test-propagator-ot-trace lint-propagator-ot-trace @@ -319,7 +319,7 @@ envlist = ; below mean these dependencies are being used: ; 0: pika>=0.12.0,<1.0.0 ; 1: pika>=1.0.0 - py3{8,9,10,11}-test-instrumentation-sio-pika-{0,1} + py3{8,9,10,11,12}-test-instrumentation-sio-pika-{0,1} pypy3-test-instrumentation-sio-pika-{0,1} lint-instrumentation-sio-pika @@ -330,7 +330,7 @@ envlist = ; 1: aio_pika==8.3.0 ; 2: aio_pika==9.0.5 ; 3: aio_pika==9.4.1 - py3{8,9,10,11}-test-instrumentation-aio-pika-{0,1,2,3} + py3{8,9,10,11,12}-test-instrumentation-aio-pika-{0,1,2,3} pypy3-test-instrumentation-aio-pika-{0,1,2,3} lint-instrumentation-aio-pika @@ -340,21 +340,21 @@ envlist = lint-instrumentation-kafka-python ; opentelemetry-instrumentation-confluent-kafka - py3{8,9,10,11}-test-instrumentation-confluent-kafka + py3{8,9,10,11,12}-test-instrumentation-confluent-kafka pypy3-test-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka ; opentelemetry-instrumentation-asyncio - py3{8,9,10,11}-test-instrumentation-asyncio + py3{8,9,10,11,12}-test-instrumentation-asyncio lint-instrumentation-asyncio ; opentelemetry-instrumentation-cassandra - py3{8,9,10,11}-test-instrumentation-cassandra + py3{8,9,10,11,12}-test-instrumentation-cassandra pypy3-test-instrumentation-cassandra lint-instrumentation-cassandra ; opentelemetry-processor-baggage - py3{8,9,10,11}-test-processor-baggage + py3{8,9,10,11,12}-test-processor-baggage pypy3-test-processor-baggage ; requires snappy headers to be available on the system lint-processor-baggage @@ -407,7 +407,7 @@ commands_pre = celery: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk celery: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils py3{8,9}-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt - py3{10,11}-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt + py3{10,11,12}-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt pypy3-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt lint-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -531,8 +531,8 @@ commands_pre = py3{8,9}-test-instrumentation-django-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt py3{8,9}-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt py3{8,9}-test-instrumentation-django-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt - py3{10,11}-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{10,11}-test-instrumentation-django-3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt + py3{10,11,12}-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + py3{10,11,12}-test-instrumentation-django-3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt pypy3-test-instrumentation-django-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt pypy3-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt lint-instrumentation-django: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -577,7 +577,7 @@ commands_pre = psycopg: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk psycopg: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils py3{8,9}-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt - py3{10,11}-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt + py3{10,11,12}-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt pypy3-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt lint-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt diff --git a/util/opentelemetry-util-http/pyproject.toml b/util/opentelemetry-util-http/pyproject.toml index 88724caf1a..0e632a81b3 100644 --- a/util/opentelemetry-util-http/pyproject.toml +++ b/util/opentelemetry-util-http/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] [project.urls] From 20e68e38e7d0bce21b78060272c5422e09be0112 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 11 Jun 2024 18:18:56 +0200 Subject: [PATCH 037/335] requirements: bump Jinja2 to 3.1.4 (#2593) --- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-jinja2/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index f02ffb216f..8f713687bd 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -14,7 +14,7 @@ idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 -Jinja2==3.1.3 +Jinja2==3.1.4 MarkupSafe==2.1.5 multidict==6.0.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index fcedc7c695..fad2f5e2b0 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -5,7 +5,7 @@ Flask==2.1.3 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 -Jinja2==3.1.3 +Jinja2==3.1.4 MarkupSafe==2.1.2 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index c6773ad2e9..919ee6d431 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -5,7 +5,7 @@ Flask==2.2.0 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 -Jinja2==3.1.3 +Jinja2==3.1.4 MarkupSafe==2.1.2 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 98638a4ed6..16d91d2058 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -6,7 +6,7 @@ Flask==3.0.2 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 -Jinja2==3.1.3 +Jinja2==3.1.4 MarkupSafe==2.1.2 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index 6461129bee..e547f9bd20 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.7.2 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -Jinja2==3.1.3 +Jinja2==3.1.4 MarkupSafe==2.0.1 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 121fdacf3c..a68f40e5d2 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -10,7 +10,7 @@ idna==3.7 importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 -Jinja2==3.1.3 +Jinja2==3.1.4 MarkupSafe==2.1.5 packaging==24.0 pluggy==1.5.0 From af9675cf04f3172c53fbb89c31c1b91954cb36d2 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 11 Jun 2024 18:44:16 +0200 Subject: [PATCH 038/335] requirements: bump sqlparse to 0.5.0 (#2595) --- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index 2203da3e33..a6162e7c00 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -9,7 +9,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 pytz==2024.1 -sqlparse==0.4.4 +sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index bf7239cce6..58f5d5c88b 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -9,7 +9,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 pytz==2024.1 -sqlparse==0.4.4 +sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 03d4570977..ffc43f4023 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -9,7 +9,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -sqlparse==0.4.4 +sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index ec200f92ef..92ebaa83e4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -sqlparse==0.4.4 +sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 From da78275a5560c155492b0b18f48e4db250974226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:16:18 -0300 Subject: [PATCH 039/335] increase delta for fastapi flaky test (#2591) --- .../tests/test_fastapi_instrumentation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 948bd343db..a7cd5045ee 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -254,7 +254,7 @@ def test_basic_metric_success(self): dict(point.attributes), ) self.assertEqual(point.count, 1) - self.assertAlmostEqual(duration, point.sum, delta=30) + self.assertAlmostEqual(duration, point.sum, delta=40) if isinstance(point, NumberDataPoint): self.assertDictEqual( expected_requests_count_attributes, @@ -279,7 +279,7 @@ def test_basic_post_request_metric_success(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) if metric.name == "http.server.duration": - self.assertAlmostEqual(duration, point.sum, delta=30) + self.assertAlmostEqual(duration, point.sum, delta=40) elif metric.name == "http.server.response.size": self.assertEqual(response_size, point.sum) elif metric.name == "http.server.request.size": From 184d8d45b99b6a60e5621bc39c31959c5ea28340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:02:24 -0300 Subject: [PATCH 040/335] Change issue templates to forms (#2602) --- .github/ISSUE_TEMPLATE/bug_report.md | 19 ------ .github/ISSUE_TEMPLATE/bug_report.yaml | 66 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 4 ++ .github/ISSUE_TEMPLATE/feature_request.md | 19 ------ .github/ISSUE_TEMPLATE/feature_request.yaml | 50 ++++++++++++++++ 5 files changed, 120 insertions(+), 38 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2597b185d0..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Bug Report -about: Create a report to help us improve -labels: bug ---- - -**Describe your environment** Describe any aspect of your environment relevant to the problem, including your Python version, [platform](https://docs.python.org/3/library/platform.html), version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main. - -**Steps to reproduce** -Describe exactly how to reproduce the error. Include a code sample if applicable. - -**What is the expected behavior?** -What did you expect to see? - -**What is the actual behavior?** -What did you see instead? - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000000..6718481a76 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,66 @@ +--- +name: Bug Report +description: Create a report to help us improve +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down your bug as quickly as possible. + + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-python-contrib/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if your bug is already addressed. + + - type: textarea + id: environment + attributes: + label: Describe your environment + description: | + Please describe any aspect of your environment relevant to the problem, including your Python version, [platform](https://docs.python.org/3/library/platform.html), version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main. + value: | + OS: (e.g, Ubuntu) + Python version: (e.g., Python 3.8.10) + Package version: (e.g., 0.46.0) + + - type: textarea + attributes: + label: What happened? + description: Please provide as much detail as you reasonably can. + validations: + required: true + + - type: textarea + attributes: + label: Steps to Reproduce + description: Provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) if possible and the needed steps to reproduce the problem. + validations: + required: true + + - type: textarea + attributes: + label: Expected Result + description: What did you expect to see? + validations: + required: true + + - type: textarea + attributes: + label: Actual Result + description: What did you see instead? + validations: + required: true + + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Add any other context about the problem here. + placeholder: Any additional information... + + - type: dropdown + id: contribute + attributes: + label: Would you like to implement a fix? + description: For guidance on how to get started, refer to the [contribution guide](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/CONTRIBUTING.md). + options: + - "No" + - "Yes" diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..f6acad9c9b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: Slack + url: https://cloud-native.slack.com/archives/C01PD4HUVBL + about: Or the `#otel-python` channel in the CNCF Slack instance. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 973549ab2d..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Feature Request -about: Suggest an idea for this project -labels: feature-request ---- - -Before opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first. - -**Is your feature request related to a problem?** -If so, provide a concise description of the problem. - -**Describe the solution you'd like** -What do you want to happen instead? What is the expected behavior? - -**Describe alternatives you've considered** -Which alternative solutions or features have you considered? - -**Additional context** -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000000..270409a495 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,50 @@ +--- +name: Feature Request +description: Suggest an idea for this project +labels: [feature-request] +body: + - type: markdown + attributes: + value: | + Before opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first. + - type: textarea + id: related-problem + attributes: + label: What problem do you want to solve? + description: Is your feature request related to a problem? If so, provide a concise description of the problem. + placeholder: Describe the problem and include relevant issue IDs + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe the solution you'd like + description: What do you want to happen instead? What is the expected behavior? + placeholder: I'd like to ... + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you've considered + description: Which alternative solutions or features have you considered? + placeholder: Some potential solutions + validations: + required: false + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: Add any other context about the feature request here. + placeholder: Some related requests in other projects or upstream spec proposals. + validations: + required: false + - type: dropdown + id: contribute + attributes: + label: Would you like to implement a fix? + description: | + For guidance on how to get started, refer to the [contribution guide](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/CONTRIBUTING.md). + options: + - "No" + - "Yes" From 477b73cd9ae965ed98cccb746c74b4f063c81075 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 12 Jun 2024 17:14:11 +0200 Subject: [PATCH 041/335] requirements: bump requests to 2.32.3 (#2603) --- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-fastapi/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements.txt | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 7c3ab4d83e..ffd5916ae7 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -13,7 +13,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 python-snappy==0.7.1 -requests==2.31.0 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.1 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 8f713687bd..0a9c451d33 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -22,7 +22,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -requests==2.31.0 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.1 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 9f3bbd7508..8d8aad2f0e 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -24,7 +24,7 @@ pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 PyYAML==6.0.1 -requests==2.31.0 +requests==2.32.3 responses==0.25.0 s3transfer==0.10.0 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index 29c6c90230..f52060f22e 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -24,7 +24,7 @@ pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 PyYAML==6.0.1 -requests==2.31.0 +requests==2.32.3 responses==0.25.0 s3transfer==0.7.0 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 3806570105..c73b0ed688 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -19,7 +19,7 @@ pydantic==2.6.2 pydantic_core==2.16.3 pytest==7.4.4 pytest-benchmark==4.0.0 -requests==2.31.0 +requests==2.32.3 sniffio==1.3.0 starlette==0.36.3 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 16458d96d4..1270d12eb1 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -11,7 +11,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -requests==2.31.0 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.9.0 urllib3==2.2.1 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 53f85db350..882f0e165a 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -15,7 +15,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -requests==2.31.0 +requests==2.32.3 sniffio==1.3.0 starlette==0.13.8 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index a68f40e5d2..86ef01b096 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -17,7 +17,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -requests==2.31.0 +requests==2.32.3 tomli==2.0.1 tornado==6.4 typing_extensions==4.9.0 diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index bbe805e794..26f637bbb2 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -10,7 +10,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 -requests==2.31.0 +requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.1 From 361da3e45e99cc42e571c6e3f9913d37e51da89d Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 14 Jun 2024 00:56:04 +0200 Subject: [PATCH 042/335] botocore: bump moto to latest (#2605) So we can bump Werkzeug too. --- .../test-requirements.txt | 6 +- .../tests/test_botocore_dynamodb.py | 48 +++++++++----- .../tests/test_botocore_instrumentation.py | 62 ++++++++----------- .../tests/test_botocore_lambda.py | 8 +-- .../tests/test_botocore_sns.py | 10 +-- .../tests/test_botocore_sqs.py | 10 +-- 6 files changed, 76 insertions(+), 68 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index f52060f22e..c61d546e07 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -13,8 +13,8 @@ importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.4 jmespath==1.0.1 -MarkupSafe==2.0.1 -moto==3.1.19 +MarkupSafe==2.1.5 +moto==5.0.9 packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 @@ -31,7 +31,7 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 urllib3==1.26.18 -Werkzeug==2.1.2 +Werkzeug==3.0.3 wrapt==1.16.0 xmltodict==0.13.0 zipp==3.17.0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py index 12ebe8f2b7..2240baff3a 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_dynamodb.py @@ -16,7 +16,7 @@ from unittest import mock import botocore.session -from moto import mock_dynamodb2 # pylint: disable=import-error +from moto import mock_aws # pylint: disable=import-error from opentelemetry.instrumentation.botocore import BotocoreInstrumentor from opentelemetry.instrumentation.botocore.extensions.dynamodb import ( @@ -184,7 +184,7 @@ def assert_extension_item_col_metrics(self, operation: str): ) self.assert_item_col_metrics(span) - @mock_dynamodb2 + @mock_aws def test_batch_get_item(self): table_name1 = "test_table1" table_name2 = "test_table2" @@ -203,7 +203,7 @@ def test_batch_get_item(self): self.assert_table_names(span, table_name1, table_name2) self.assert_consumed_capacity(span, table_name1, table_name2) - @mock_dynamodb2 + @mock_aws def test_batch_write_item(self): table_name1 = "test_table1" table_name2 = "test_table2" @@ -224,7 +224,7 @@ def test_batch_write_item(self): self.assert_consumed_capacity(span, table_name1, table_name2) self.assert_item_col_metrics(span) - @mock_dynamodb2 + @mock_aws def test_create_table(self): local_sec_idx = { "IndexName": "local_sec_idx", @@ -268,7 +268,7 @@ def test_create_table(self): ) self.assert_provisioned_read_cap(span, 42) - @mock_dynamodb2 + @mock_aws def test_delete_item(self): self._create_prepared_table() @@ -297,7 +297,7 @@ def test_delete_item_consumed_capacity(self): def test_delete_item_item_collection_metrics(self): self.assert_extension_item_col_metrics("DeleteItem") - @mock_dynamodb2 + @mock_aws def test_delete_table(self): self._create_prepared_table() @@ -306,7 +306,7 @@ def test_delete_table(self): span = self.assert_span("DeleteTable") self.assert_table_names(span, self.default_table_name) - @mock_dynamodb2 + @mock_aws def test_describe_table(self): self._create_prepared_table() @@ -315,15 +315,31 @@ def test_describe_table(self): span = self.assert_span("DescribeTable") self.assert_table_names(span, self.default_table_name) - @mock_dynamodb2 - def test_get_item(self): + @mock_aws + def test_get_item_expression(self): + self._create_prepared_table() + + self.client.get_item( + TableName=self.default_table_name, + Key={"id": {"S": "1"}}, + ConsistentRead=True, + ProjectionExpression="PE", + ReturnConsumedCapacity="TOTAL", + ) + + span = self.assert_span("GetItem") + self.assert_table_names(span, self.default_table_name) + self.assert_consistent_read(span, True) + self.assert_consumed_capacity(span, self.default_table_name) + + @mock_aws + def test_get_item_non_expression(self): self._create_prepared_table() self.client.get_item( TableName=self.default_table_name, Key={"id": {"S": "1"}}, ConsistentRead=True, - AttributesToGet=["id"], ProjectionExpression="PE", ReturnConsumedCapacity="TOTAL", ) @@ -334,7 +350,7 @@ def test_get_item(self): self.assert_projection(span, "PE") self.assert_consumed_capacity(span, self.default_table_name) - @mock_dynamodb2 + @mock_aws def test_list_tables(self): self._create_table(TableName="my_table") self._create_prepared_table() @@ -351,7 +367,7 @@ def test_list_tables(self): ) self.assertEqual(5, span.attributes[SpanAttributes.AWS_DYNAMODB_LIMIT]) - @mock_dynamodb2 + @mock_aws def test_put_item(self): table = "test_table" self._create_prepared_table(TableName=table) @@ -372,7 +388,7 @@ def test_put_item(self): def test_put_item_item_collection_metrics(self): self.assert_extension_item_col_metrics("PutItem") - @mock_dynamodb2 + @mock_aws def test_query(self): self._create_prepared_table() @@ -407,7 +423,7 @@ def test_query(self): self.assert_select(span, "ALL_ATTRIBUTES") self.assert_consumed_capacity(span, self.default_table_name) - @mock_dynamodb2 + @mock_aws def test_scan(self): self._create_prepared_table() @@ -444,7 +460,7 @@ def test_scan(self): self.assert_select(span, "ALL_ATTRIBUTES") self.assert_consumed_capacity(span, self.default_table_name) - @mock_dynamodb2 + @mock_aws def test_update_item(self): self._create_prepared_table() @@ -465,7 +481,7 @@ def test_update_item(self): def test_update_item_item_collection_metrics(self): self.assert_extension_item_col_metrics("UpdateItem") - @mock_dynamodb2 + @mock_aws def test_update_table(self): self._create_prepared_table() diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py index bb6d283399..62357a3336 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py @@ -12,19 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. import json -from unittest.mock import Mock, patch +from unittest.mock import ANY, Mock, patch import botocore.session from botocore.exceptions import ParamValidationError -from moto import ( # pylint: disable=import-error - mock_ec2, - mock_kinesis, - mock_kms, - mock_s3, - mock_sqs, - mock_sts, - mock_xray, -) +from moto import mock_aws # pylint: disable=import-error from opentelemetry import trace as trace_api from opentelemetry.instrumentation.botocore import BotocoreInstrumentor @@ -39,7 +31,7 @@ from opentelemetry.test.test_base import TestBase from opentelemetry.trace.span import format_span_id, format_trace_id -_REQUEST_ID_REGEX_MATCH = r"[A-Z0-9]{52}" +_REQUEST_ID_REGEX_MATCH = r"[A-Za-z0-9]{52}" # pylint:disable=too-many-public-methods @@ -102,7 +94,7 @@ def assert_span( self.assertEqual(f"{service}.{operation}", span.name) return span - @mock_ec2 + @mock_aws def test_traced_client(self): ec2 = self._make_client("ec2") @@ -111,7 +103,7 @@ def test_traced_client(self): request_id = "fdcdcab1-ae5c-489e-9c33-4637c5dda355" self.assert_span("EC2", "DescribeInstances", request_id=request_id) - @mock_ec2 + @mock_aws def test_not_recording(self): mock_tracer = Mock() mock_span = Mock() @@ -126,7 +118,7 @@ def test_not_recording(self): self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) - @mock_s3 + @mock_aws def test_exception(self): s3 = self._make_client("s3") @@ -149,14 +141,14 @@ def test_exception(self): self.assertIn(SpanAttributes.EXCEPTION_TYPE, event.attributes) self.assertIn(SpanAttributes.EXCEPTION_MESSAGE, event.attributes) - @mock_s3 + @mock_aws def test_s3_client(self): s3 = self._make_client("s3") s3.list_buckets() self.assert_span("S3", "ListBuckets") - @mock_s3 + @mock_aws def test_s3_put(self): s3 = self._make_client("s3") @@ -174,7 +166,7 @@ def test_s3_put(self): s3.get_object(Bucket="mybucket", Key="foo") self.assert_span("S3", "GetObject", request_id=_REQUEST_ID_REGEX_MATCH) - @mock_sqs + @mock_aws def test_sqs_client(self): sqs = self._make_client("sqs") @@ -184,7 +176,7 @@ def test_sqs_client(self): "SQS", "ListQueues", request_id=_REQUEST_ID_REGEX_MATCH ) - @mock_sqs + @mock_aws def test_sqs_send_message(self): sqs = self._make_client("sqs") test_queue_name = "test_queue_name" @@ -205,14 +197,14 @@ def test_sqs_send_message(self): attributes={"aws.queue_url": queue_url}, ) - @mock_kinesis + @mock_aws def test_kinesis_client(self): kinesis = self._make_client("kinesis") kinesis.list_streams() self.assert_span("Kinesis", "ListStreams") - @mock_kinesis + @mock_aws def test_unpatch(self): kinesis = self._make_client("kinesis") @@ -221,7 +213,7 @@ def test_unpatch(self): kinesis.list_streams() self.assertEqual(0, len(self.memory_exporter.get_finished_spans())) - @mock_ec2 + @mock_aws def test_uninstrument_does_not_inject_headers(self): headers = {} @@ -240,7 +232,7 @@ def intercept_headers(**kwargs): self.assertNotIn(TRACE_HEADER_KEY, headers) - @mock_sqs + @mock_aws def test_double_patch(self): sqs = self._make_client("sqs") @@ -252,19 +244,19 @@ def test_double_patch(self): "SQS", "ListQueues", request_id=_REQUEST_ID_REGEX_MATCH ) - @mock_kms + @mock_aws def test_kms_client(self): kms = self._make_client("kms") kms.list_keys(Limit=21) span = self.assert_only_span() + expected = self._default_span_attributes("KMS", "ListKeys") + expected["aws.request_id"] = ANY # check for exact attribute set to make sure not to leak any kms secrets - self.assertEqual( - self._default_span_attributes("KMS", "ListKeys"), span.attributes - ) + self.assertEqual(expected, dict(span.attributes)) - @mock_sts + @mock_aws def test_sts_client(self): sts = self._make_client("sts") @@ -272,11 +264,11 @@ def test_sts_client(self): span = self.assert_only_span() expected = self._default_span_attributes("STS", "GetCallerIdentity") - expected["aws.request_id"] = "c6104cbe-af31-11e0-8154-cbc7ccf896c7" + expected["aws.request_id"] = ANY # check for exact attribute set to make sure not to leak any sts secrets - self.assertEqual(expected, span.attributes) + self.assertEqual(expected, dict(span.attributes)) - @mock_ec2 + @mock_aws def test_propagator_injects_into_request(self): headers = {} previous_propagator = get_global_textmap() @@ -316,7 +308,7 @@ def check_headers(**kwargs): finally: set_global_textmap(previous_propagator) - @mock_ec2 + @mock_aws def test_override_xray_propagator_injects_into_request(self): headers = {} @@ -335,7 +327,7 @@ def check_headers(**kwargs): self.assertNotIn(MockTextMapPropagator.TRACE_ID_KEY, headers) self.assertNotIn(MockTextMapPropagator.SPAN_ID_KEY, headers) - @mock_xray + @mock_aws def test_suppress_instrumentation_xray_client(self): xray_client = self._make_client("xray") with suppress_instrumentation(): @@ -343,7 +335,7 @@ def test_suppress_instrumentation_xray_client(self): xray_client.put_trace_segments(TraceSegmentDocuments=["str2"]) self.assertEqual(0, len(self.get_finished_spans())) - @mock_xray + @mock_aws def test_suppress_http_instrumentation_xray_client(self): xray_client = self._make_client("xray") with suppress_http_instrumentation(): @@ -351,7 +343,7 @@ def test_suppress_http_instrumentation_xray_client(self): xray_client.put_trace_segments(TraceSegmentDocuments=["str2"]) self.assertEqual(2, len(self.get_finished_spans())) - @mock_s3 + @mock_aws def test_request_hook(self): request_hook_service_attribute_name = "request_hook.service_name" request_hook_operation_attribute_name = "request_hook.operation_name" @@ -386,7 +378,7 @@ def request_hook(span, service_name, operation_name, api_params): }, ) - @mock_s3 + @mock_aws def test_response_hook(self): response_hook_service_attribute_name = "request_hook.service_name" response_hook_operation_attribute_name = "response_hook.operation_name" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py index 7388323100..098edfc896 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py @@ -19,7 +19,7 @@ from unittest import mock import botocore.session -from moto import mock_iam, mock_lambda # pylint: disable=import-error +from moto import mock_aws # pylint: disable=import-error from pytest import mark from opentelemetry.instrumentation.botocore import BotocoreInstrumentor @@ -96,12 +96,12 @@ def _create_extension(operation: str) -> _LambdaExtension: mock_call_context = mock.MagicMock(operation=operation, params={}) return _LambdaExtension(mock_call_context) - @mock_lambda + @mock_aws def test_list_functions(self): self.client.list_functions() self.assert_span("ListFunctions") - @mock_iam + @mock_aws def _create_role_and_get_arn(self) -> str: return self.iam_client.create_role( RoleName="my-role", @@ -131,7 +131,7 @@ def _create_lambda_function(self, function_name: str, function_code: str): sys.platform == "win32", reason="requires docker and Github CI Windows does not have docker installed by default", ) - @mock_lambda + @mock_aws def test_invoke(self): previous_propagator = get_global_textmap() try: diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sns.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sns.py index e2b4c55732..5d6b94f145 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sns.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sns.py @@ -18,7 +18,7 @@ import botocore.session from botocore.awsrequest import AWSResponse -from moto import mock_sns +from moto import mock_aws from opentelemetry.instrumentation.botocore import BotocoreInstrumentor from opentelemetry.semconv.trace import ( @@ -91,11 +91,11 @@ def assert_injected_span(self, message_attrs: Dict[str, Any], span: Span): self.assertEqual(span_context.trace_id, int(trace_parent[1], 16)) self.assertEqual(span_context.span_id, int(trace_parent[2], 16)) - @mock_sns + @mock_aws def test_publish_to_topic_arn(self): self._test_publish_to_arn("TopicArn") - @mock_sns + @mock_aws def test_publish_to_target_arn(self): self._test_publish_to_arn("TargetArn") @@ -125,7 +125,7 @@ def _test_publish_to_arn(self, arg_name: str): span.attributes["messaging.destination.name"], ) - @mock_sns + @mock_aws def test_publish_to_phone_number(self): phone_number = "+10000000000" self.client.publish( @@ -138,7 +138,7 @@ def test_publish_to_phone_number(self): phone_number, span.attributes[SpanAttributes.MESSAGING_DESTINATION] ) - @mock_sns + @mock_aws def test_publish_injects_span(self): message_attrs = {} topic_arn = self._create_topic() diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sqs.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sqs.py index 6bcffd9274..cdf39e4ece 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sqs.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_sqs.py @@ -1,5 +1,5 @@ import botocore.session -from moto import mock_sqs +from moto import mock_aws from opentelemetry.instrumentation.botocore import BotocoreInstrumentor from opentelemetry.semconv.trace import SpanAttributes @@ -22,7 +22,7 @@ def tearDown(self): super().tearDown() BotocoreInstrumentor().uninstrument() - @mock_sqs + @mock_aws def test_sqs_messaging_send_message(self): create_queue_result = self.client.create_queue( QueueName="test_queue_name" @@ -51,7 +51,7 @@ def test_sqs_messaging_send_message(self): response["MessageId"], ) - @mock_sqs + @mock_aws def test_sqs_messaging_send_message_batch(self): create_queue_result = self.client.create_queue( QueueName="test_queue_name" @@ -85,7 +85,7 @@ def test_sqs_messaging_send_message_batch(self): response["Successful"][0]["MessageId"], ) - @mock_sqs + @mock_aws def test_sqs_messaging_receive_message(self): create_queue_result = self.client.create_queue( QueueName="test_queue_name" @@ -116,7 +116,7 @@ def test_sqs_messaging_receive_message(self): message_result["Messages"][0]["MessageId"], ) - @mock_sqs + @mock_aws def test_sqs_messaging_failed_operation(self): with self.assertRaises(Exception): self.client.send_message( From 881a179e3b16ecff305faf4d74566b6b954c4dd2 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 13 Jun 2024 17:50:45 -0600 Subject: [PATCH 043/335] Add xray propagators that prioritizes xray environment variable (#2573) * Add AwsXrayLambdaPropagator Fixes #2457 * Remove unnecessary AWS_TRACE_HEADER_PROP * Add docstring * Fix nit * Add no environment variable test case * Add test case for valid context * Remove ipdb * Fix lint * Add missing entry point --- CHANGELOG.md | 5 + .../pyproject.toml | 1 + .../propagators/aws/aws_xray_propagator.py | 32 ++++ .../tests/test_aws_xray_lambda_propagator.py | 164 ++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e17542b104..eead4dd886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- `opentelemetry-sdk-extension-aws` Add AwsXrayLambdaPropagator + ([#2573](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2573)) + ### Breaking changes - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette` Use `tracer` and `meter` of originating components instead of one from `asgi` middleware diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 69fd0bbbfa..4a3e22269a 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -30,6 +30,7 @@ dependencies = [ [project.entry-points.opentelemetry_propagator] xray = "opentelemetry.propagators.aws:AwsXRayPropagator" +xray_lambda = "opentelemetry.propagators.aws:AwsXRayLambdaPropagator" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/propagator/opentelemetry-propagator-aws-xray" diff --git a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py index 4e4a6872ea..4966218211 100644 --- a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py +++ b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py @@ -58,6 +58,7 @@ import logging import typing +from os import environ from opentelemetry import trace from opentelemetry.context import Context @@ -71,6 +72,7 @@ ) TRACE_HEADER_KEY = "X-Amzn-Trace-Id" +AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID" KV_PAIR_DELIMITER = ";" KEY_AND_VALUE_DELIMITER = "=" @@ -324,3 +326,33 @@ def fields(self): """Returns a set with the fields set in `inject`.""" return {TRACE_HEADER_KEY} + + +class AwsXrayLambdaPropagator(AwsXRayPropagator): + """Implementation of the AWS X-Ray Trace Header propagation protocol but + with special handling for Lambda's ``_X_AMZN_TRACE_ID` environment + variable. + """ + + def extract( + self, + carrier: CarrierT, + context: typing.Optional[Context] = None, + getter: Getter[CarrierT] = default_getter, + ) -> Context: + + xray_context = super().extract(carrier, context=context, getter=getter) + + if trace.get_current_span(context=context).get_span_context().is_valid: + return xray_context + + trace_header = environ.get(AWS_TRACE_HEADER_ENV_KEY) + + if trace_header is None: + return xray_context + + return super().extract( + {TRACE_HEADER_KEY: trace_header}, + context=xray_context, + getter=getter, + ) diff --git a/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py b/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py new file mode 100644 index 0000000000..a0432d1457 --- /dev/null +++ b/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py @@ -0,0 +1,164 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from os import environ +from unittest import TestCase +from unittest.mock import patch + +from requests.structures import CaseInsensitiveDict + +from opentelemetry.context import get_current +from opentelemetry.propagators.aws.aws_xray_propagator import ( + TRACE_HEADER_KEY, + AwsXrayLambdaPropagator, +) +from opentelemetry.propagators.textmap import DefaultGetter +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.trace import ( + Link, + NonRecordingSpan, + SpanContext, + TraceState, + get_current_span, + use_span, +) + + +class AwsXRayLambdaPropagatorTest(TestCase): + + def test_extract_no_environment_variable(self): + + actual_context = get_current_span( + AwsXrayLambdaPropagator().extract( + {}, context=get_current(), getter=DefaultGetter() + ) + ).get_span_context() + + self.assertEqual(hex(actual_context.trace_id), "0x0") + self.assertEqual(hex(actual_context.span_id), "0x0") + self.assertFalse( + actual_context.trace_flags.sampled, + ) + self.assertEqual(actual_context.trace_state, TraceState.get_default()) + + def test_extract_no_environment_variable_valid_context(self): + + with use_span(NonRecordingSpan(SpanContext(1, 2, False))): + + actual_context = get_current_span( + AwsXrayLambdaPropagator().extract( + {}, context=get_current(), getter=DefaultGetter() + ) + ).get_span_context() + + self.assertEqual(hex(actual_context.trace_id), "0x1") + self.assertEqual(hex(actual_context.span_id), "0x2") + self.assertFalse( + actual_context.trace_flags.sampled, + ) + self.assertEqual( + actual_context.trace_state, TraceState.get_default() + ) + + @patch.dict( + environ, + { + "_X_AMZN_TRACE_ID": ( + "Root=1-00000001-d188f8fa79d48a391a778fa6;" + "Parent=53995c3f42cd8ad8;Sampled=1;Foo=Bar" + ) + }, + ) + def test_extract_from_environment_variable(self): + + actual_context = get_current_span( + AwsXrayLambdaPropagator().extract( + {}, context=get_current(), getter=DefaultGetter() + ) + ).get_span_context() + + self.assertEqual( + hex(actual_context.trace_id), "0x1d188f8fa79d48a391a778fa6" + ) + self.assertEqual(hex(actual_context.span_id), "0x53995c3f42cd8ad8") + self.assertTrue( + actual_context.trace_flags.sampled, + ) + self.assertEqual(actual_context.trace_state, TraceState.get_default()) + + @patch.dict( + environ, + { + "_X_AMZN_TRACE_ID": ( + "Root=1-00000002-240000000000000000000002;" + "Parent=1600000000000002;Sampled=1;Foo=Bar" + ) + }, + ) + def test_add_link_from_environment_variable(self): + + propagator = AwsXrayLambdaPropagator() + + default_getter = DefaultGetter() + + carrier = CaseInsensitiveDict( + { + TRACE_HEADER_KEY: ( + "Root=1-00000001-240000000000000000000001;" + "Parent=1600000000000001;Sampled=1" + ) + } + ) + + extracted_context = propagator.extract( + carrier, context=get_current(), getter=default_getter + ) + + link_context = propagator.extract( + carrier, context=extracted_context, getter=default_getter + ) + + span = ReadableSpan( + "test", parent=extracted_context, links=[Link(link_context)] + ) + + span_parent_context = get_current_span(span.parent).get_span_context() + + self.assertEqual( + hex(span_parent_context.trace_id), "0x2240000000000000000000002" + ) + self.assertEqual( + hex(span_parent_context.span_id), "0x1600000000000002" + ) + self.assertTrue( + span_parent_context.trace_flags.sampled, + ) + self.assertEqual( + span_parent_context.trace_state, TraceState.get_default() + ) + + span_link_context = get_current_span( + span.links[0].context + ).get_span_context() + + self.assertEqual( + hex(span_link_context.trace_id), "0x1240000000000000000000001" + ) + self.assertEqual(hex(span_link_context.span_id), "0x1600000000000001") + self.assertTrue( + span_link_context.trace_flags.sampled, + ) + self.assertEqual( + span_link_context.trace_state, TraceState.get_default() + ) From 6be205e60445c7c485a487158fb26538e3ab1c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:53:28 -0300 Subject: [PATCH 044/335] consistently use of suppress_instrumentation utils (#2590) --- CHANGELOG.md | 2 + .../aiohttp_server/__init__.py | 14 ++--- .../tests/test_aiohttp_server_integration.py | 29 +++++++++- .../instrumentation/httpx/__init__.py | 10 ++-- .../tests/test_httpx_integration.py | 17 ++---- .../opentelemetry/instrumentation/utils.py | 15 ++++-- .../tests/test_utils.py | 54 +++++++++++++++++++ .../CHANGELOG.md | 5 ++ .../resource/detector/azure/vm.py | 24 ++++----- 9 files changed, 125 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eead4dd886..05199a98a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) - Add Python 3.12 support ([#2572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2572)) +- `opentelemetry-instrumentation-aiohttp-server`, `opentelemetry-instrumentation-httpx` Ensure consistently use of suppress_instrumentation utils + ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py index c1ab960818..2e519ac1c5 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py @@ -19,12 +19,14 @@ from aiohttp import web from multidict import CIMultiDictProxy -from opentelemetry import context, metrics, trace -from opentelemetry.context import _SUPPRESS_HTTP_INSTRUMENTATION_KEY +from opentelemetry import metrics, trace from opentelemetry.instrumentation.aiohttp_server.package import _instruments from opentelemetry.instrumentation.aiohttp_server.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.utils import http_status_to_status_code +from opentelemetry.instrumentation.utils import ( + http_status_to_status_code, + is_http_instrumentation_enabled, +) from opentelemetry.propagate import extract from opentelemetry.propagators.textmap import Getter from opentelemetry.semconv.metrics import MetricInstruments @@ -191,10 +193,8 @@ def keys(self, carrier: Dict) -> List: @web.middleware async def middleware(request, handler): """Middleware for aiohttp implementing tracing logic""" - if ( - context.get_value("suppress_instrumentation") - or context.get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY) - or _excluded_urls.url_disabled(request.url.path) + if not is_http_instrumentation_enabled() or _excluded_urls.url_disabled( + request.url.path ): return await handler(request) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py index b5e8ec468f..e9dfb11389 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py @@ -23,6 +23,7 @@ from opentelemetry.instrumentation.aiohttp_server import ( AioHttpServerInstrumentor, ) +from opentelemetry.instrumentation.utils import suppress_http_instrumentation from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.globals_test import reset_trace_globals from opentelemetry.test.test_base import TestBase @@ -64,16 +65,25 @@ async def default_handler(request, status=200): return aiohttp.web.Response(status=status) +@pytest.fixture(name="suppress") +def fixture_suppress(): + return False + + @pytest_asyncio.fixture(name="server_fixture") -async def fixture_server_fixture(tracer, aiohttp_server): +async def fixture_server_fixture(tracer, aiohttp_server, suppress): _, memory_exporter = tracer AioHttpServerInstrumentor().instrument() app = aiohttp.web.Application() app.add_routes([aiohttp.web.get("/test-path", default_handler)]) + if suppress: + with suppress_http_instrumentation(): + server = await aiohttp_server(app) + else: + server = await aiohttp_server(app) - server = await aiohttp_server(app) yield server, app memory_exporter.clear() @@ -128,3 +138,18 @@ async def test_status_code_instrumentation( f"http://{server.host}:{server.port}{url}" == span.attributes[SpanAttributes.HTTP_URL] ) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("suppress", [True]) +async def test_suppress_instrumentation( + tracer, server_fixture, aiohttp_client +): + _, memory_exporter = tracer + server, _ = server_fixture + assert len(memory_exporter.get_finished_spans()) == 0 + + client = await aiohttp_client(server) + await client.get("/test-path") + + assert len(memory_exporter.get_finished_spans()) == 0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 850e76eea3..5404b2f025 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -196,11 +196,13 @@ async def async_response_hook(span, request, response): import httpx -from opentelemetry import context from opentelemetry.instrumentation.httpx.package import _instruments from opentelemetry.instrumentation.httpx.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.utils import http_status_to_status_code +from opentelemetry.instrumentation.utils import ( + http_status_to_status_code, + is_http_instrumentation_enabled, +) from opentelemetry.propagate import inject from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import SpanKind, TracerProvider, get_tracer @@ -347,7 +349,7 @@ def handle_request( httpx.Response, ]: """Add request info to span.""" - if context.get_value("suppress_instrumentation"): + if not is_http_instrumentation_enabled(): return self._transport.handle_request(*args, **kwargs) method, url, headers, stream, extensions = _extract_parameters( @@ -438,7 +440,7 @@ async def handle_async_request(self, *args, **kwargs) -> typing.Union[ httpx.Response, ]: """Add request info to span.""" - if context.get_value("suppress_instrumentation"): + if not is_http_instrumentation_enabled(): return await self._transport.handle_async_request(*args, **kwargs) method, url, headers, stream, extensions = _extract_parameters( diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index d64db1a8f5..06ad963ab0 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -21,12 +21,13 @@ import respx import opentelemetry.instrumentation.httpx -from opentelemetry import context, trace +from opentelemetry import trace from opentelemetry.instrumentation.httpx import ( AsyncOpenTelemetryTransport, HTTPXClientInstrumentor, SyncOpenTelemetryTransport, ) +from opentelemetry.instrumentation.utils import suppress_http_instrumentation from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.sdk import resources from opentelemetry.semconv.trace import SpanAttributes @@ -191,14 +192,9 @@ def test_not_foundbasic(self): ) def test_suppress_instrumentation(self): - token = context.attach( - context.set_value("suppress_instrumentation", True) - ) - try: + with suppress_http_instrumentation(): result = self.perform_request(self.URL) self.assertEqual(result.text, "Hello!") - finally: - context.detach(token) self.assert_span(num_spans=0) @@ -512,15 +508,10 @@ def test_not_recording(self): def test_suppress_instrumentation_new_client(self): HTTPXClientInstrumentor().instrument() - token = context.attach( - context.set_value("suppress_instrumentation", True) - ) - try: + with suppress_http_instrumentation(): client = self.create_client() result = self.perform_request(self.URL, client=client) self.assertEqual(result.text, "Hello!") - finally: - context.detach(token) self.assert_span(num_spans=0) HTTPXClientInstrumentor().uninstrument() diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index 318aaeaa74..73c000ee9c 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -37,6 +37,10 @@ propagator = TraceContextTextMapPropagator() +_SUPPRESS_INSTRUMENTATION_KEY_PLAIN = ( + "suppress_instrumentation" # Set for backward compatibility +) + def extract_attributes_from_object( obj: any, attributes: Sequence[str], existing: Dict[str, str] = None @@ -161,9 +165,10 @@ def _python_path_without_directory(python_path, directory, path_separator): def is_instrumentation_enabled() -> bool: - if context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): - return False - return True + return not ( + context.get_value(_SUPPRESS_INSTRUMENTATION_KEY) + or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY_PLAIN) + ) def is_http_instrumentation_enabled() -> bool: @@ -188,7 +193,9 @@ def _suppress_instrumentation(*keys: str) -> Iterable[None]: @contextmanager def suppress_instrumentation() -> Iterable[None]: """Suppress instrumentation within the context.""" - with _suppress_instrumentation(_SUPPRESS_INSTRUMENTATION_KEY): + with _suppress_instrumentation( + _SUPPRESS_INSTRUMENTATION_KEY, _SUPPRESS_INSTRUMENTATION_KEY_PLAIN + ): yield diff --git a/opentelemetry-instrumentation/tests/test_utils.py b/opentelemetry-instrumentation/tests/test_utils.py index cf6cfdfd37..d3807a1bdb 100644 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ b/opentelemetry-instrumentation/tests/test_utils.py @@ -15,10 +15,20 @@ import unittest from http import HTTPStatus +from opentelemetry.context import ( + _SUPPRESS_HTTP_INSTRUMENTATION_KEY, + _SUPPRESS_INSTRUMENTATION_KEY, + get_current, + get_value, +) from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment from opentelemetry.instrumentation.utils import ( _python_path_without_directory, http_status_to_status_code, + is_http_instrumentation_enabled, + is_instrumentation_enabled, + suppress_http_instrumentation, + suppress_instrumentation, ) from opentelemetry.trace import StatusCode @@ -186,3 +196,47 @@ def test_add_sql_comments_without_comments(self): ) self.assertEqual(commented_sql_without_semicolon, "Select 1") + + def test_is_instrumentation_enabled_by_default(self): + self.assertTrue(is_instrumentation_enabled()) + self.assertTrue(is_http_instrumentation_enabled()) + + def test_suppress_instrumentation(self): + with suppress_instrumentation(): + self.assertFalse(is_instrumentation_enabled()) + self.assertFalse(is_http_instrumentation_enabled()) + + self.assertTrue(is_instrumentation_enabled()) + self.assertTrue(is_http_instrumentation_enabled()) + + def test_suppress_http_instrumentation(self): + with suppress_http_instrumentation(): + self.assertFalse(is_http_instrumentation_enabled()) + self.assertTrue(is_instrumentation_enabled()) + + self.assertTrue(is_instrumentation_enabled()) + self.assertTrue(is_http_instrumentation_enabled()) + + def test_suppress_instrumentation_key(self): + self.assertIsNone(get_value(_SUPPRESS_INSTRUMENTATION_KEY)) + self.assertIsNone(get_value("suppress_instrumentation")) + + with suppress_instrumentation(): + ctx = get_current() + self.assertIn(_SUPPRESS_INSTRUMENTATION_KEY, ctx) + self.assertIn("suppress_instrumentation", ctx) + self.assertTrue(get_value(_SUPPRESS_INSTRUMENTATION_KEY)) + self.assertTrue(get_value("suppress_instrumentation")) + + self.assertIsNone(get_value(_SUPPRESS_INSTRUMENTATION_KEY)) + self.assertIsNone(get_value("suppress_instrumentation")) + + def test_suppress_http_instrumentation_key(self): + self.assertIsNone(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY)) + + with suppress_http_instrumentation(): + ctx = get_current() + self.assertIn(_SUPPRESS_HTTP_INSTRUMENTATION_KEY, ctx) + self.assertTrue(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY)) + + self.assertIsNone(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY)) diff --git a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md index f77fce18f1..5e16c83d63 100644 --- a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md +++ b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +- Ensure consistently use of suppress_instrumentation utils + ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) + ## Version 0.1.5 (2024-05-16) - Ignore vm detector if already in other rps diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py index 2112282949..63281a46e5 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py @@ -17,12 +17,7 @@ from urllib.error import URLError from urllib.request import Request, urlopen -from opentelemetry.context import ( - _SUPPRESS_INSTRUMENTATION_KEY, - attach, - detach, - set_value, -) +from opentelemetry.instrumentation.utils import suppress_instrumentation from opentelemetry.sdk.resources import Resource, ResourceDetector from opentelemetry.semconv.resource import ( CloudPlatformValues, @@ -46,15 +41,14 @@ class AzureVMResourceDetector(ResourceDetector): def detect(self) -> "Resource": attributes = {} if not _can_ignore_vm_detect(): - token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) - metadata_json = _get_azure_vm_metadata() - if not metadata_json: - return Resource(attributes) - for attribute_key in _EXPECTED_AZURE_AMS_ATTRIBUTES: - attributes[attribute_key] = _get_attribute_from_metadata( - metadata_json, attribute_key - ) - detach(token) + with suppress_instrumentation(): + metadata_json = _get_azure_vm_metadata() + if not metadata_json: + return Resource(attributes) + for attribute_key in _EXPECTED_AZURE_AMS_ATTRIBUTES: + attributes[attribute_key] = _get_attribute_from_metadata( + metadata_json, attribute_key + ) return Resource(attributes) From 795c93376c9db0a426aa62d79e28389e4ef27cf6 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 14 Jun 2024 19:01:11 +0200 Subject: [PATCH 045/335] instrumentation/pymysql: bump pymysql to 1.1.1 in test requirements (#2608) --- .../opentelemetry-instrumentation-pymysql/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index 9a1076a543..5f2d8b7783 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -5,7 +5,7 @@ iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 -PyMySQL==1.1.0 +PyMySQL==1.1.1 pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 From 91a69d4c9971a6b7e1c2b7b3eeb5856a7a300b0f Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 14 Jun 2024 19:11:24 +0200 Subject: [PATCH 046/335] aiohttp: bump aiohttp in test requirements to latest (#2607) --- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 0a9c451d33..1110776262 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.9.3 +aiohttp==3.9.4 aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index c62da59804..fe7582a2bb 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.9.3 +aiohttp==3.9.4 aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 From daa84a6c6386dbebbb6a57c012257a93e4267113 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 14 Jun 2024 19:20:50 +0200 Subject: [PATCH 047/335] instrumentation/tornado: bump to latest 6.4.1 in test-requirements (#2606) --- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 86ef01b096..700911213a 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -19,7 +19,7 @@ pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 -tornado==6.4 +tornado==6.4.1 typing_extensions==4.9.0 urllib3==2.2.1 Werkzeug==3.0.3 From b94c5906fd9cc723ba81da965f89ae73264ec835 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 17 Jun 2024 09:20:17 -0700 Subject: [PATCH 048/335] Use generated symbols from semantic conventions package (#2611) --- CHANGELOG.md | 2 + .../instrumentation/flask/__init__.py | 8 +- .../tests/test_programmatic.py | 6 +- .../instrumentation/requests/__init__.py | 38 +++---- .../tests/test_requests_integration.py | 100 +++++++++--------- .../instrumentation/wsgi/__init__.py | 14 +-- .../tests/test_wsgi_middleware.py | 72 +++++++------ .../opentelemetry/instrumentation/_semconv.py | 93 ++++++++-------- 8 files changed, 172 insertions(+), 161 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05199a98a4..bbbf49f453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2572)) - `opentelemetry-instrumentation-aiohttp-server`, `opentelemetry-instrumentation-httpx` Ensure consistently use of suppress_instrumentation utils ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) +- Reference symbols from generated semantic conventions + ([#2611](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2611)) ## Version 1.25.0/0.46b0 (2024-05-31) 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 f2e0ee34cc..34e9b5ea50 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -251,7 +251,6 @@ def response_hook(span: Span, status: str, response_headers: List): import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _METRIC_ATTRIBUTES_SERVER_DURATION_NAME, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -268,6 +267,9 @@ def response_hook(span: Span, status: str, response_headers: List): from opentelemetry.instrumentation.utils import _start_internal_or_server_span from opentelemetry.metrics import get_meter from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.util.http import ( get_excluded_urls, @@ -553,7 +555,7 @@ def __init__(self, *args, **kwargs): duration_histogram_new = None if _report_new(_InstrumentedFlask._sem_conv_opt_in_mode): duration_histogram_new = meter.create_histogram( - name=_METRIC_ATTRIBUTES_SERVER_DURATION_NAME, + name=HTTP_SERVER_REQUEST_DURATION, unit="s", description="measures the duration of the inbound HTTP request", ) @@ -684,7 +686,7 @@ def instrument_app( duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): duration_histogram_new = meter.create_histogram( - name=_METRIC_ATTRIBUTES_SERVER_DURATION_NAME, + name=HTTP_SERVER_REQUEST_DURATION, unit="s", description="measures the duration of the inbound HTTP request", ) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index d30a100b0e..f50d3245a0 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -20,7 +20,6 @@ from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( - _SPAN_ATTRIBUTES_ERROR_TYPE, OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, @@ -40,6 +39,7 @@ NumberDataPoint, ) from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.util.http import ( @@ -379,7 +379,7 @@ def test_internal_error_new_semconv(self): SpanAttributes.URL_PATH: "/hello/500", SpanAttributes.HTTP_ROUTE: "/hello/", SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 500, - _SPAN_ATTRIBUTES_ERROR_TYPE: "500", + ERROR_TYPE: "500", SpanAttributes.URL_SCHEME: "http", } ) @@ -405,7 +405,7 @@ def test_internal_error_both_semconv(self): { SpanAttributes.URL_PATH: "/hello/500", SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 500, - _SPAN_ATTRIBUTES_ERROR_TYPE: "500", + ERROR_TYPE: "500", SpanAttributes.URL_SCHEME: "http", } ) diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 8c54482a46..18cc3e767c 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -59,10 +59,6 @@ from requests.structures import CaseInsensitiveDict from opentelemetry.instrumentation._semconv import ( - _METRIC_ATTRIBUTES_CLIENT_DURATION_NAME, - _SPAN_ATTRIBUTES_ERROR_TYPE, - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT, _client_duration_attrs_new, _client_duration_attrs_old, _filter_semconv_duration_attrs, @@ -91,7 +87,15 @@ ) from opentelemetry.metrics import Histogram, get_meter from opentelemetry.propagate import inject +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PEER_ADDRESS, + NETWORK_PEER_PORT, +) from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_DURATION, +) from opentelemetry.trace import SpanKind, Tracer, get_tracer from opentelemetry.trace.span import Span from opentelemetry.trace.status import StatusCode @@ -191,9 +195,7 @@ def get_or_create_headers(): sem_conv_opt_in_mode, ) # Use semconv library when available - span_attributes[_SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS] = ( - parsed_url.hostname - ) + span_attributes[NETWORK_PEER_ADDRESS] = parsed_url.hostname if parsed_url.port: _set_http_peer_port_client( metric_labels, parsed_url.port, sem_conv_opt_in_mode @@ -203,9 +205,7 @@ def get_or_create_headers(): span_attributes, parsed_url.port, sem_conv_opt_in_mode ) # Use semconv library when available - span_attributes[_SPAN_ATTRIBUTES_NETWORK_PEER_PORT] = ( - parsed_url.port - ) + span_attributes[NETWORK_PEER_PORT] = parsed_url.port except ValueError: pass @@ -250,12 +250,8 @@ def get_or_create_headers(): _report_new(sem_conv_opt_in_mode) and status_code is StatusCode.ERROR ): - span_attributes[_SPAN_ATTRIBUTES_ERROR_TYPE] = str( - result.status_code - ) - metric_labels[_SPAN_ATTRIBUTES_ERROR_TYPE] = str( - result.status_code - ) + span_attributes[ERROR_TYPE] = str(result.status_code) + metric_labels[ERROR_TYPE] = str(result.status_code) if result.raw is not None: version = getattr(result.raw, "version", None) @@ -278,12 +274,8 @@ def get_or_create_headers(): response_hook(span, request, result) if exception is not None and _report_new(sem_conv_opt_in_mode): - span.set_attribute( - _SPAN_ATTRIBUTES_ERROR_TYPE, type(exception).__qualname__ - ) - metric_labels[_SPAN_ATTRIBUTES_ERROR_TYPE] = type( - exception - ).__qualname__ + span.set_attribute(ERROR_TYPE, type(exception).__qualname__) + metric_labels[ERROR_TYPE] = type(exception).__qualname__ if duration_histogram_old is not None: duration_attrs_old = _filter_semconv_duration_attrs( @@ -403,7 +395,7 @@ def _instrument(self, **kwargs): duration_histogram_new = None if _report_new(semconv_opt_in_mode): duration_histogram_new = meter.create_histogram( - name=_METRIC_ATTRIBUTES_CLIENT_DURATION_NAME, + name=HTTP_CLIENT_REQUEST_DURATION, unit="s", description="Duration of HTTP client requests.", ) diff --git a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py index d85d70e20e..75518fc8d3 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py +++ b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py @@ -23,9 +23,6 @@ import opentelemetry.instrumentation.requests from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( - _SPAN_ATTRIBUTES_ERROR_TYPE, - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT, OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, ) @@ -36,6 +33,21 @@ ) from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.sdk import resources +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PEER_ADDRESS, + NETWORK_PEER_PORT, + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import URL_FULL from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase @@ -176,14 +188,14 @@ def test_basic_new_semconv(self): self.assertEqual( span.attributes, { - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.URL_FULL: url_with_port, - SpanAttributes.SERVER_ADDRESS: "mock", - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS: "mock", - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", - SpanAttributes.SERVER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT: 80, + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url_with_port, + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + HTTP_RESPONSE_STATUS_CODE: 200, + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_PORT: 80, + NETWORK_PEER_PORT: 80, }, ) @@ -213,19 +225,19 @@ def test_basic_both_semconv(self): span.attributes, { SpanAttributes.HTTP_METHOD: "GET", - SpanAttributes.HTTP_REQUEST_METHOD: "GET", + HTTP_REQUEST_METHOD: "GET", SpanAttributes.HTTP_URL: url_with_port, - SpanAttributes.URL_FULL: url_with_port, + URL_FULL: url_with_port, SpanAttributes.HTTP_HOST: "mock", - SpanAttributes.SERVER_ADDRESS: "mock", - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS: "mock", + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", SpanAttributes.NET_PEER_PORT: 80, SpanAttributes.HTTP_STATUS_CODE: 200, - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, + HTTP_RESPONSE_STATUS_CODE: 200, SpanAttributes.HTTP_FLAVOR: "1.1", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", - SpanAttributes.SERVER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT: 80, + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_PORT: 80, + NETWORK_PEER_PORT: 80, }, ) @@ -328,12 +340,8 @@ def test_not_foundbasic_new_semconv(self): span = self.assert_span() - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_RESPONSE_STATUS_CODE), 404 - ) - self.assertEqual( - span.attributes.get(_SPAN_ATTRIBUTES_ERROR_TYPE), "404" - ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404) + self.assertEqual(span.attributes.get(ERROR_TYPE), "404") self.assertIs( span.status.status_code, @@ -355,12 +363,8 @@ def test_not_foundbasic_both_semconv(self): self.assertEqual( span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 404 ) - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_RESPONSE_STATUS_CODE), 404 - ) - self.assertEqual( - span.attributes.get(_SPAN_ATTRIBUTES_ERROR_TYPE), "404" - ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404) + self.assertEqual(span.attributes.get(ERROR_TYPE), "404") self.assertIs( span.status.status_code, @@ -527,13 +531,13 @@ def test_requests_exception_new_semconv(self, *_, **__): self.assertEqual( span.attributes, { - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.URL_FULL: url_with_port, - SpanAttributes.SERVER_ADDRESS: "mock", - SpanAttributes.SERVER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS: "mock", - _SPAN_ATTRIBUTES_ERROR_TYPE: "RequestException", + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url_with_port, + SERVER_ADDRESS: "mock", + SERVER_PORT: 80, + NETWORK_PEER_PORT: 80, + NETWORK_PEER_ADDRESS: "mock", + ERROR_TYPE: "RequestException", }, ) self.assertEqual(span.status.status_code, StatusCode.ERROR) @@ -724,11 +728,11 @@ def test_basic_metric_new_semconv(self): self.perform_request(self.URL) expected_attributes = { - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.SERVER_ADDRESS: "examplehost", - SpanAttributes.SERVER_PORT: 8000, - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 200, + SERVER_ADDRESS: "examplehost", + SERVER_PORT: 8000, + HTTP_REQUEST_METHOD: "GET", + NETWORK_PROTOCOL_VERSION: "1.1", } for ( resource_metrics @@ -760,11 +764,11 @@ def test_basic_metric_both_semconv(self): } expected_attributes_new = { - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.SERVER_ADDRESS: "examplehost", - SpanAttributes.SERVER_PORT: 8000, - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 200, + SERVER_ADDRESS: "examplehost", + SERVER_PORT: 8000, + HTTP_REQUEST_METHOD: "GET", + NETWORK_PROTOCOL_VERSION: "1.1", } for ( diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 810a07e315..6a1883fa7e 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -214,8 +214,6 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _METRIC_ATTRIBUTES_SERVER_DURATION_NAME, - _SPAN_ATTRIBUTES_ERROR_TYPE, _filter_semconv_active_request_count_attr, _filter_semconv_duration_attrs, _get_schema_url, @@ -244,7 +242,11 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he from opentelemetry.instrumentation.wsgi.version import __version__ from opentelemetry.metrics import get_meter from opentelemetry.propagators.textmap import Getter +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import ( @@ -573,7 +575,7 @@ def __init__( self.duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): self.duration_histogram_new = self.meter.create_histogram( - name=_METRIC_ATTRIBUTES_SERVER_DURATION_NAME, + name=HTTP_SERVER_REQUEST_DURATION, unit="s", description="measures the duration of the inbound HTTP request", ) @@ -670,11 +672,9 @@ def __call__(self, environ, start_response): return _end_span_after_iterating(iterable, span, token) except Exception as ex: if _report_new(self._sem_conv_opt_in_mode): - req_attrs[_SPAN_ATTRIBUTES_ERROR_TYPE] = type(ex).__qualname__ + req_attrs[ERROR_TYPE] = type(ex).__qualname__ if span.is_recording(): - span.set_attribute( - _SPAN_ATTRIBUTES_ERROR_TYPE, type(ex).__qualname__ - ) + span.set_attribute(ERROR_TYPE, type(ex).__qualname__) span.set_status(Status(StatusCode.ERROR, str(ex))) span.end() if token is not None: diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py index 2b26cbb5f9..777d19f41d 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py @@ -36,6 +36,23 @@ NumberDataPoint, ) from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import ( + URL_FULL, + URL_PATH, + URL_QUERY, + URL_SCHEME, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase @@ -237,11 +254,11 @@ def validate_response( SpanAttributes.NET_HOST_NAME: "127.0.0.1", } expected_attributes_new = { - SpanAttributes.SERVER_PORT: 80, - SpanAttributes.SERVER_ADDRESS: "127.0.0.1", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.0", - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.URL_SCHEME: "http", + SERVER_PORT: 80, + SERVER_ADDRESS: "127.0.0.1", + NETWORK_PROTOCOL_VERSION: "1.0", + HTTP_RESPONSE_STATUS_CODE: 200, + URL_SCHEME: "http", } if old_sem_conv: expected_attributes.update(expected_attributes_old) @@ -253,9 +270,7 @@ def validate_response( if old_sem_conv: expected_attributes[SpanAttributes.HTTP_METHOD] = http_method if new_sem_conv: - expected_attributes[SpanAttributes.HTTP_REQUEST_METHOD] = ( - http_method - ) + expected_attributes[HTTP_REQUEST_METHOD] = http_method self.assertEqual(span_list[0].attributes, expected_attributes) def test_basic_wsgi_call(self): @@ -517,13 +532,13 @@ def test_request_attributes_new_semconv(self): self.assertDictEqual( attrs, { - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.SERVER_ADDRESS: "127.0.0.1", - SpanAttributes.SERVER_PORT: 80, - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.0", - SpanAttributes.URL_PATH: "/", - SpanAttributes.URL_QUERY: "foo=bar", - SpanAttributes.URL_SCHEME: "http", + HTTP_REQUEST_METHOD: "GET", + SERVER_ADDRESS: "127.0.0.1", + SERVER_PORT: 80, + NETWORK_PROTOCOL_VERSION: "1.0", + URL_PATH: "/", + URL_QUERY: "foo=bar", + URL_SCHEME: "http", }, ) @@ -543,11 +558,10 @@ def validate_url( SpanAttributes.HTTP_SERVER_NAME: parts.hostname, # Not true in the general case, but for all tests. } expected_new = { - SpanAttributes.SERVER_PORT: parts.port - or (80 if parts.scheme == "http" else 443), - SpanAttributes.SERVER_ADDRESS: parts.hostname, - SpanAttributes.URL_PATH: parts.path, - SpanAttributes.URL_QUERY: parts.query, + SERVER_PORT: parts.port or (80 if parts.scheme == "http" else 443), + SERVER_ADDRESS: parts.hostname, + URL_PATH: parts.path, + URL_QUERY: parts.query, } if old_semconv: if raw: @@ -560,17 +574,15 @@ def validate_url( expected_old[SpanAttributes.HTTP_HOST] = parts.hostname if new_semconv: if raw: - expected_new[SpanAttributes.URL_PATH] = expected_url.split( - parts.path, 1 - )[1] + expected_new[URL_PATH] = expected_url.split(parts.path, 1)[1] if parts.query: - expected_new[SpanAttributes.URL_QUERY] = ( - expected_url.split(parts.query, 1)[1] - ) + expected_new[URL_QUERY] = expected_url.split( + parts.query, 1 + )[1] else: - expected_new[SpanAttributes.HTTP_URL] = expected_url + expected_new[URL_FULL] = expected_url if has_host: - expected_new[SpanAttributes.SERVER_ADDRESS] = parts.hostname + expected_new[SERVER_ADDRESS] = parts.hostname attrs = otel_wsgi.collect_request_attributes(self.environ) self.assertGreaterEqual( @@ -720,8 +732,8 @@ def test_request_attributes_with_full_request_uri(self): SpanAttributes.HTTP_TARGET: "http://docs.python.org:80/3/library/urllib.parse.html?highlight=params#url-parsing", } expected_new = { - SpanAttributes.URL_PATH: "/3/library/urllib.parse.html", - SpanAttributes.URL_QUERY: "highlight=params", + URL_PATH: "/3/library/urllib.parse.html", + URL_QUERY: "highlight=params", } self.assertGreaterEqual( otel_wsgi.collect_request_attributes(self.environ).items(), diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index efe3c75f70..baa06ff99b 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -17,16 +17,27 @@ from enum import Enum from opentelemetry.instrumentation.utils import http_status_to_status_code +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import ( + URL_FULL, + URL_SCHEME, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode -# TODO: will come through semconv package once updated -_SPAN_ATTRIBUTES_ERROR_TYPE = "error.type" -_SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS = "network.peer.address" -_SPAN_ATTRIBUTES_NETWORK_PEER_PORT = "network.peer.port" -_METRIC_ATTRIBUTES_CLIENT_DURATION_NAME = "http.client.request.duration" -_METRIC_ATTRIBUTES_SERVER_DURATION_NAME = "http.server.request.duration" - _client_duration_attrs_old = [ SpanAttributes.HTTP_STATUS_CODE, SpanAttributes.HTTP_HOST, @@ -38,14 +49,14 @@ ] _client_duration_attrs_new = [ - _SPAN_ATTRIBUTES_ERROR_TYPE, - SpanAttributes.HTTP_REQUEST_METHOD, - SpanAttributes.HTTP_RESPONSE_STATUS_CODE, - SpanAttributes.NETWORK_PROTOCOL_VERSION, - SpanAttributes.SERVER_ADDRESS, - SpanAttributes.SERVER_PORT, + ERROR_TYPE, + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + NETWORK_PROTOCOL_VERSION, + SERVER_ADDRESS, + SERVER_PORT, # TODO: Support opt-in for scheme in new semconv - # SpanAttributes.URL_SCHEME, + # URL_SCHEME, ] _server_duration_attrs_old = [ @@ -60,12 +71,12 @@ ] _server_duration_attrs_new = [ - _SPAN_ATTRIBUTES_ERROR_TYPE, - SpanAttributes.HTTP_REQUEST_METHOD, - SpanAttributes.HTTP_RESPONSE_STATUS_CODE, - SpanAttributes.HTTP_ROUTE, - SpanAttributes.NETWORK_PROTOCOL_VERSION, - SpanAttributes.URL_SCHEME, + ERROR_TYPE, + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, + NETWORK_PROTOCOL_VERSION, + URL_SCHEME, ] _server_active_requests_count_attrs_old = [ @@ -79,8 +90,8 @@ ] _server_active_requests_count_attrs_new = [ - SpanAttributes.HTTP_REQUEST_METHOD, - SpanAttributes.URL_SCHEME, + HTTP_REQUEST_METHOD, + URL_SCHEME, ] OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" @@ -202,46 +213,40 @@ def _set_http_method(result, original, normalized, sem_conv_opt_in_mode): # See https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes # Method is case sensitive. "http.request.method_original" should not be sanitized or automatically capitalized. if original != normalized and _report_new(sem_conv_opt_in_mode): - set_string_attribute( - result, SpanAttributes.HTTP_REQUEST_METHOD_ORIGINAL, original - ) + set_string_attribute(result, HTTP_REQUEST_METHOD_ORIGINAL, original) if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_METHOD, normalized) if _report_new(sem_conv_opt_in_mode): - set_string_attribute( - result, SpanAttributes.HTTP_REQUEST_METHOD, normalized - ) + set_string_attribute(result, HTTP_REQUEST_METHOD, normalized) def _set_http_status_code(result, code, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_int_attribute(result, SpanAttributes.HTTP_STATUS_CODE, code) if _report_new(sem_conv_opt_in_mode): - set_int_attribute( - result, SpanAttributes.HTTP_RESPONSE_STATUS_CODE, code - ) + set_int_attribute(result, HTTP_RESPONSE_STATUS_CODE, code) def _set_http_url(result, url, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_URL, url) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.URL_FULL, url) + set_string_attribute(result, URL_FULL, url) def _set_http_scheme(result, scheme, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_SCHEME, scheme) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.URL_SCHEME, scheme) + set_string_attribute(result, URL_SCHEME, scheme) def _set_http_host(result, host, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_HOST, host) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.SERVER_ADDRESS, host) + set_string_attribute(result, SERVER_ADDRESS, host) # Client @@ -251,23 +256,21 @@ def _set_http_net_peer_name_client(result, peer_name, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.NET_PEER_NAME, peer_name) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.SERVER_ADDRESS, peer_name) + set_string_attribute(result, SERVER_ADDRESS, peer_name) def _set_http_peer_port_client(result, port, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port) if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, SpanAttributes.SERVER_PORT, port) + set_int_attribute(result, SERVER_PORT, port) def _set_http_network_protocol_version(result, version, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version) if _report_new(sem_conv_opt_in_mode): - set_string_attribute( - result, SpanAttributes.NETWORK_PROTOCOL_VERSION, version - ) + set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) # Server @@ -347,8 +350,8 @@ def _set_status( ): if status_code < 0: if _report_new(sem_conv_opt_in_mode): - span.set_attribute(_SPAN_ATTRIBUTES_ERROR_TYPE, status_code_str) - metrics_attributes[_SPAN_ATTRIBUTES_ERROR_TYPE] = status_code_str + span.set_attribute(ERROR_TYPE, status_code_str) + metrics_attributes[ERROR_TYPE] = status_code_str span.set_status( Status( @@ -370,12 +373,8 @@ def _set_status( status_code ) if status == StatusCode.ERROR: - span.set_attribute( - _SPAN_ATTRIBUTES_ERROR_TYPE, status_code_str - ) - metrics_attributes[_SPAN_ATTRIBUTES_ERROR_TYPE] = ( - status_code_str - ) + span.set_attribute(ERROR_TYPE, status_code_str) + metrics_attributes[ERROR_TYPE] = status_code_str span.set_status(Status(status)) From 4a75c535a7ed435b466d05a1b1ee1d440e327576 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 20 Jun 2024 17:39:13 +0200 Subject: [PATCH 049/335] boto: bump cryptography in test requirements (#2615) --- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 8d8aad2f0e..495e23255a 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -5,7 +5,7 @@ botocore==1.34.44 certifi==2024.2.2 cffi==1.16.0 charset-normalizer==3.3.2 -cryptography==42.0.3 +cryptography==42.0.5 Deprecated==1.2.14 docker==7.0.0 idna==3.7 From d93afc877385778ebfe2d3df554c6a036fac651e Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 20 Jun 2024 17:48:06 +0200 Subject: [PATCH 050/335] Bump docs and dev requirements with dependabot security warnings (#2614) --- dev-requirements.txt | 2 +- docs-requirements.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 60db203e2d..3289650ac8 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -14,7 +14,7 @@ bleach==4.1.0 # transient dependency for readme-renderer protobuf~=3.13 markupsafe>=2.0.1 codespell==2.1.0 -requests==2.31.0 +requests==2.32.3 ruamel.yaml==0.17.21 flaky==3.7.0 pre-commit==3.7.0; python_version >= '3.9' diff --git a/docs-requirements.txt b/docs-requirements.txt index 72f4472902..6a822e44da 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -38,8 +38,8 @@ mysqlclient~=2.1.1 psutil>=5 psycopg~=3.1.17 pika>=0.12.0 -pymongo~=3.1 -PyMySQL~=0.9.3 +pymongo~=4.6.3 +PyMySQL~=1.1.1 pyramid>=1.7 redis>=2.6 remoulade>=0.50 From 3669b477bdf2c8631ab223599baa4b34ee18cf0d Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 20 Jun 2024 18:26:01 +0200 Subject: [PATCH 051/335] requirements: Bump urllib3 to latest (#2618) --- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-fastapi/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements.txt | 2 +- tox.ini | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index ffd5916ae7..b41245cd1f 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -16,7 +16,7 @@ python-snappy==0.7.1 requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e exporter/opentelemetry-exporter-prometheus-remote-write diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 1110776262..f597361598 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -25,7 +25,7 @@ pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 Werkzeug==3.0.3 wrapt==1.16.0 yarl==1.9.4 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 495e23255a..54c8bb0558 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -30,7 +30,7 @@ s3transfer==0.10.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 -urllib3==1.26.18 +urllib3==1.26.19 Werkzeug==2.3.8 wrapt==1.16.0 xmltodict==0.13.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index 8ddfd9983f..54fcf790d7 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -15,7 +15,7 @@ s3transfer==0.10.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 -urllib3==1.26.18 +urllib3==1.26.19 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index c61d546e07..f9fe9abe8a 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -30,7 +30,7 @@ s3transfer==0.7.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 -urllib3==1.26.18 +urllib3==1.26.19 Werkzeug==3.0.3 wrapt==1.16.0 xmltodict==0.13.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index dac65a0f01..e6d9bb6f9d 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -13,7 +13,7 @@ python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==1.26.18 +urllib3==1.26.19 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index c9baa38ad6..12e3a1c229 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -13,7 +13,7 @@ python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==1.26.18 +urllib3==1.26.19 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index b852eff7cb..f34d67d9c8 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -14,7 +14,7 @@ python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index c73b0ed688..2116980b3f 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -24,7 +24,7 @@ sniffio==1.3.0 starlette==0.36.3 tomli==2.0.1 typing_extensions==4.9.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 1270d12eb1..c5c8f84366 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -14,7 +14,7 @@ pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 typing_extensions==4.9.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 882f0e165a..a582353901 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -20,7 +20,7 @@ sniffio==1.3.0 starlette==0.13.8 tomli==2.0.1 typing_extensions==4.9.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 700911213a..14ac028083 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -21,7 +21,7 @@ requests==2.32.3 tomli==2.0.1 tornado==6.4.1 typing_extensions==4.9.0 -urllib3==2.2.1 +urllib3==2.2.2 Werkzeug==3.0.3 wrapt==1.16.0 zipp==3.17.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index 05a76b1bcb..6eb6272dbf 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -10,7 +10,7 @@ pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==1.26.18 +urllib3==1.26.19 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 9c6d596068..402beb85b9 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -10,7 +10,7 @@ pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e opentelemetry-instrumentation diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index 26f637bbb2..5e15e1c4a1 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -13,7 +13,7 @@ pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 -urllib3==2.2.1 +urllib3==2.2.2 wrapt==1.16.0 zipp==3.17.0 -e propagator/opentelemetry-propagator-aws-xray diff --git a/tox.ini b/tox.ini index e0d5d79cbc..54d2354952 100644 --- a/tox.ini +++ b/tox.ini @@ -1282,7 +1282,7 @@ deps = tomli==2.0.1 typing_extensions==4.10.0 tzdata==2024.1 - urllib3==1.26.18 + urllib3==1.26.19 vine==5.1.0 wcwidth==0.2.13 websocket-client==0.59.0 From b776ac92a888c98bae154ae9f5f944c6b127531c Mon Sep 17 00:00:00 2001 From: Fools <54661071+Charlie-lizhihan@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:06:14 +0100 Subject: [PATCH 052/335] Update CONTRIBUTING.md (#2620) --- CONTRIBUTING.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2cd72f12d8..1cc77b184a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,7 +55,7 @@ some aspects of development, including testing against multiple Python versions. To install `tox`, run: ```sh -pip install tox +$ pip install tox ``` You can run `tox` with the following arguments: @@ -128,13 +128,14 @@ pull requests (PRs). To create a new PR, fork the project in GitHub and clone the upstream repo: ```sh -git clone https://github.com/open-telemetry/opentelemetry-python-contrib.git +$ git clone https://github.com/open-telemetry/opentelemetry-python-contrib.git +$ cd opentelemetry-python-contrib ``` Add your fork as an origin: ```sh -git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-python-contrib.git +$ git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-python-contrib.git ``` Run tests: @@ -148,10 +149,10 @@ $ tox # execute in the root of the repository Check out a new branch, make modifications and push the branch to your fork: ```sh -git checkout -b feature +$ git checkout -b feature # edit files -git commit -git push fork feature +$ git commit +$ git push fork feature ``` Open a pull request against the main `opentelemetry-python-contrib` repo. From fecb1e2862ddda7c071a4ed413c36382dfc27cbe Mon Sep 17 00:00:00 2001 From: Rytis Bagdziunas Date: Thu, 20 Jun 2024 19:19:20 +0200 Subject: [PATCH 053/335] Added recording of exceptions in Pyramid (#2622) --- CHANGELOG.md | 2 ++ .../instrumentation/pyramid/callbacks.py | 13 ++++++++- .../tests/pyramid_base_test.py | 2 +- .../tests/test_automatic.py | 1 + .../tests/test_programmatic.py | 29 +++++++++++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbbf49f453..e67ae4a3b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-pyramid` Record exceptions raised when serving a request + ([#2622](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2622)) - `opentelemetry-sdk-extension-aws` Add AwsXrayLambdaPropagator ([#2573](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2573)) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index ede3e09608..d0010ed8d0 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -31,6 +31,7 @@ from opentelemetry.metrics import get_meter from opentelemetry.semconv.metrics import MetricInstruments from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import get_excluded_urls TWEEN_NAME = "opentelemetry.instrumentation.pyramid.trace_tween_factory" @@ -180,6 +181,7 @@ def trace_tween(request): response = None status = None + recordable_exc = None try: response = handler(request) @@ -190,11 +192,14 @@ def trace_tween(request): # As described in docs, Pyramid exceptions are all valid # response types response = exc + if isinstance(exc, HTTPServerError): + recordable_exc = exc raise - except BaseException: + except BaseException as exc: # In the case that a non-HTTPException is bubbled up we # should infer a internal server error and raise status = "500 InternalServerError" + recordable_exc = exc raise finally: duration = max(round((default_timer() - start) * 1000), 0) @@ -222,6 +227,12 @@ def trace_tween(request): getattr(response, "headerlist", None), ) + if recordable_exc is not None: + span.set_status( + Status(StatusCode.ERROR, str(recordable_exc)) + ) + span.record_exception(recordable_exc) + if span.is_recording() and span.kind == trace.SpanKind.SERVER: custom_attributes = ( otel_wsgi.collect_custom_response_headers_attributes( diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py index c6b9faa196..bf23686845 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py @@ -35,7 +35,7 @@ def _hello_endpoint(request): if helloid == 204: raise exc.HTTPNoContent() if helloid == 900: - raise NotImplementedError() + raise NotImplementedError("error message") return Response("Hello: " + str(helloid)) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py index 7b48e16e17..b1d854b371 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py @@ -121,6 +121,7 @@ def test_redirect_response_is_not_an_error(self): span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 1) self.assertEqual(span_list[0].status.status_code, StatusCode.UNSET) + self.assertEqual(len(span_list[0].events), 0) PyramidInstrumentor().uninstrument() diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py index c566c301d8..0e3a5dec19 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py @@ -23,6 +23,7 @@ set_global_response_propagator, ) from opentelemetry.instrumentation.pyramid import PyramidInstrumentor +from opentelemetry.semconv.attributes import exception_attributes from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.util.http import get_excluded_urls @@ -149,6 +150,7 @@ def test_404(self): self.assertEqual(span_list[0].name, "POST /bye") self.assertEqual(span_list[0].kind, trace.SpanKind.SERVER) self.assertEqual(span_list[0].attributes, expected_attrs) + self.assertEqual(len(span_list[0].events), 0) def test_internal_error(self): expected_attrs = expected_attributes( @@ -166,6 +168,18 @@ def test_internal_error(self): self.assertEqual(span_list[0].name, "/hello/{helloid}") self.assertEqual(span_list[0].kind, trace.SpanKind.SERVER) self.assertEqual(span_list[0].attributes, expected_attrs) + self.assertEqual( + span_list[0].status.status_code, trace.StatusCode.ERROR + ) + self.assertIn( + "HTTPInternalServerError", span_list[0].status.description + ) + self.assertEqual( + span_list[0] + .events[0] + .attributes[exception_attributes.EXCEPTION_TYPE], + "pyramid.httpexceptions.HTTPInternalServerError", + ) def test_internal_exception(self): expected_attrs = expected_attributes( @@ -184,6 +198,21 @@ def test_internal_exception(self): self.assertEqual(span_list[0].name, "/hello/{helloid}") self.assertEqual(span_list[0].kind, trace.SpanKind.SERVER) self.assertEqual(span_list[0].attributes, expected_attrs) + self.assertEqual( + span_list[0].status.status_code, trace.StatusCode.ERROR + ) + self.assertEqual(span_list[0].status.description, "error message") + + expected_error_event_attrs = { + exception_attributes.EXCEPTION_TYPE: "NotImplementedError", + exception_attributes.EXCEPTION_MESSAGE: "error message", + } + self.assertEqual(span_list[0].events[0].name, "exception") + # Ensure exception event has specific attributes, but allow additional ones + self.assertLess( + expected_error_event_attrs.items(), + dict(span_list[0].events[0].attributes).items(), + ) def test_tween_list(self): tween_list = "opentelemetry.instrumentation.pyramid.trace_tween_factory\npyramid.tweens.excview_tween_factory" From feed69bcc7963e18fb0a4d64fa2d0f604a52fb22 Mon Sep 17 00:00:00 2001 From: Rytis Bagdziunas Date: Thu, 20 Jun 2024 19:35:28 +0200 Subject: [PATCH 054/335] Upgrade Werkzeug library for testing (#2623) --- .../test-requirements.txt | 2 +- .../tests/pyramid_base_test.py | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 3edddf72c3..184b03fed4 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -17,7 +17,7 @@ translationstring==1.4 typing_extensions==4.9.0 venusian==3.1.0 WebOb==1.8.7 -Werkzeug==0.16.1 +Werkzeug==3.0.3 wrapt==1.16.0 zipp==3.17.0 zope.deprecation==5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py index bf23686845..9c177433ef 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py @@ -14,12 +14,7 @@ import pyramid.httpexceptions as exc from pyramid.response import Response -from werkzeug.test import Client - -# opentelemetry-instrumentation-pyramid uses werkzeug==0.16.1 which has -# werkzeug.wrappers.BaseResponse. This is not the case for newer versions of -# werkzeug like the one lint uses. -from werkzeug.wrappers import BaseResponse # pylint: disable=no-name-in-module +from werkzeug.test import Client, TestResponse class InstrumentationTest: @@ -77,4 +72,4 @@ def excluded2_endpoint(request): ) # pylint: disable=attribute-defined-outside-init - self.client = Client(config.make_wsgi_app(), BaseResponse) + self.client = Client(config.make_wsgi_app(), TestResponse) From 41ca9027a84953fa7a069afb7daf7a8d5ddb607c Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 20 Jun 2024 19:42:48 +0200 Subject: [PATCH 055/335] instrumentation: drop dead code from aiohttp-client tests (#2625) --- .../tests/test_aiohttp_client_integration.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 2fa97f40b0..b6fe1eb57a 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -14,7 +14,6 @@ import asyncio import contextlib -import sys import typing import unittest import urllib.parse @@ -117,10 +116,6 @@ def test_status_codes(self): ) url = f"http://{host}:{port}/test-path?query=param#foobar" - # if python version is < 3.8, then the url will be - if sys.version_info[1] < 8: - url = f"http://{host}:{port}/test-path#foobar" - self.assert_spans( [ ( From a61739c9c26d8a92b209b6b2acd9a95f55d59ad6 Mon Sep 17 00:00:00 2001 From: Fools <54661071+Charlie-lizhihan@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:50:31 +0100 Subject: [PATCH 056/335] =?UTF-8?q?bugfix:=20AWS=20Lambda=20event=20source?= =?UTF-8?q?=20key=20incorrect=20for=20SNS=20in=20instrumenta=E2=80=A6=20(#?= =?UTF-8?q?2612)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++ .../instrumentation/aws_lambda/__init__.py | 6 ++-- .../test_aws_lambda_instrumentation_manual.py | 33 ++++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e67ae4a3b0..642bf90d0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. + ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) + ### Added - `opentelemetry-instrumentation-pyramid` Record exceptions raised when serving a request diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index 7614ba9813..4acf4dea90 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -306,9 +306,11 @@ def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches disable_aws_context_propagation, ) - span_kind = None try: - if lambda_event["Records"][0]["eventSource"] in { + event_source = lambda_event["Records"][0].get( + "eventSource" + ) or lambda_event["Records"][0].get("EventSource") + if event_source in { "aws:sqs", "aws:s3", "aws:sns", diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index f10953c754..ecce9ea12c 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -349,12 +349,43 @@ def test_lambda_handles_multiple_consumers(self): mock_execute_lambda({"Records": [{"eventSource": "aws:sqs"}]}) mock_execute_lambda({"Records": [{"eventSource": "aws:s3"}]}) - mock_execute_lambda({"Records": [{"eventSource": "aws:sns"}]}) + mock_execute_lambda({"Records": [{"EventSource": "aws:sns"}]}) mock_execute_lambda({"Records": [{"eventSource": "aws:dynamodb"}]}) spans = self.memory_exporter.get_finished_spans() assert spans + assert len(spans) == 4 + + for span in spans: + assert span.kind == SpanKind.CONSUMER + + test_env_patch.stop() + + def test_lambda_handles_invalid_event_source(self): + test_env_patch = mock.patch.dict( + "os.environ", + { + **os.environ, + # NOT Active Tracing + _X_AMZN_TRACE_ID: MOCK_XRAY_TRACE_CONTEXT_NOT_SAMPLED, + # NOT using the X-Ray Propagator + OTEL_PROPAGATORS: "tracecontext", + }, + ) + test_env_patch.start() + + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda({"Records": [{"eventSource": "invalid_source"}]}) + + spans = self.memory_exporter.get_finished_spans() + + assert spans + assert len(spans) == 1 + assert ( + spans[0].kind == SpanKind.SERVER + ) # Default to SERVER for unknown sources test_env_patch.stop() From f6ed62a7aa8cd674267c68f1507e3e449fd85bca Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Thu, 20 Jun 2024 23:37:26 +0100 Subject: [PATCH 057/335] Repeated headers list for ASGI frameworks (#2361) * avoid loosing repeated HTTP headers * fix fof wsgi, test in falcon * add changelog * add more tests * linting * fix falcon and flask * remove unused test * Use a list for repeated HTTP headers * linting * add changelog entry * update docs and improve fastapi tests * revert changes in wsgi based webframeworks * fix linting * Fix import path of typing symbols --------- Co-authored-by: Leighton Chen Co-authored-by: Diego Hurtado --- CHANGELOG.md | 5 ++- .../instrumentation/asgi/__init__.py | 26 +++++------ .../tests/test_asgi_custom_headers.py | 6 ++- .../instrumentation/fastapi/__init__.py | 6 +-- .../tests/test_fastapi_instrumentation.py | 43 ++++++++++++++----- .../instrumentation/starlette/__init__.py | 8 ++-- .../src/opentelemetry/util/http/__init__.py | 35 +++++++-------- 7 files changed, 77 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 642bf90d0f..b9b5478b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2425](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2425)) - `opentelemetry-instrumentation-flask` Add `http.method` to `span.name` ([#2454](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2454)) -- ASGI, FastAPI, Starlette: provide both send and receive hooks with `scope` and `message` for internal spans ([#2546](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2546)) +- Record repeated HTTP headers in lists, rather than a comma separate strings for ASGI based web frameworks + ([#2361](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2361)) +- ASGI, FastAPI, Starlette: provide both send and receive hooks with `scope` and `message` for internal spans +- ([#2546](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2546)) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index e416e8dec2..f24160fcb6 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -129,10 +129,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A The name of the added span attribute will follow the format ``http.request.header.`` where ```` is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -single item list containing all the header values. +list containing the header values. For example: -``http.request.header.custom_request_header = [","]`` +``http.request.header.custom_request_header = ["", ""]`` Response headers **************** @@ -163,10 +163,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A The name of the added span attribute will follow the format ``http.response.header.`` where ```` is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -single item list containing all the header values. +list containing the header values. For example: -``http.response.header.custom_response_header = [","]`` +``http.response.header.custom_response_header = ["", ""]`` Sanitizing headers ****************** @@ -193,9 +193,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A import typing import urllib +from collections import defaultdict from functools import wraps from timeit import default_timer -from typing import Any, Awaitable, Callable, Tuple +from typing import Any, Awaitable, Callable, DefaultDict, Tuple from asgiref.compatibility import guarantee_single_callable @@ -340,24 +341,19 @@ def collect_custom_headers_attributes( sanitize: SanitizeValue, header_regexes: list[str], normalize_names: Callable[[str], str], -) -> dict[str, str]: +) -> dict[str, list[str]]: """ Returns custom HTTP request or response headers to be added into SERVER span as span attributes. Refer specifications: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-request-and-response-headers """ - # Decode headers before processing. - headers: dict[str, str] = {} + headers: DefaultDict[str, list[str]] = defaultdict(list) raw_headers = scope_or_response_message.get("headers") if raw_headers: - for _key, _value in raw_headers: - key = _key.decode().lower() - value = _value.decode() - if key in headers: - headers[key] += f",{value}" - else: - headers[key] = value + for key, value in raw_headers: + # Decode headers before processing. + headers[key.decode()].append(value.decode()) return sanitize.sanitize_header_values( headers, diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py index 7a9c91a3e7..5394d62ff0 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py @@ -152,7 +152,8 @@ def test_http_repeat_request_headers_in_span_attributes(self): span_list = self.exporter.get_finished_spans() expected = { "http.request.header.custom_test_header_1": ( - "test-header-value-1,test-header-value-2", + "test-header-value-1", + "test-header-value-2", ), } span = next(span for span in span_list if span.kind == SpanKind.SERVER) @@ -225,7 +226,8 @@ def test_http_repeat_response_headers_in_span_attributes(self): span_list = self.exporter.get_finished_spans() expected = { "http.response.header.custom_test_header_1": ( - "test-header-value-1,test-header-value-2", + "test-header-value-1", + "test-header-value-2", ), } span = next(span for span in span_list if span.kind == SpanKind.SERVER) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 263cc0fb78..4c673d214a 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -115,7 +115,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A single item list containing all the header values. For example: -``http.request.header.custom_request_header = [","]`` +``http.request.header.custom_request_header = ["", ""]`` Response headers **************** @@ -146,10 +146,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A The name of the added span attribute will follow the format ``http.response.header.`` where ```` is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -single item list containing all the header values. +list containing the header values. For example: -``http.response.header.custom_response_header = [","]`` +``http.response.header.custom_response_header = ["", ""]`` Sanitizing headers ****************** diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index a7cd5045ee..26d9e743a8 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -11,9 +11,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - import unittest +from collections.abc import Mapping from timeit import default_timer +from typing import Tuple from unittest.mock import patch import fastapi @@ -557,6 +558,24 @@ def test_mark_span_internal_in_presence_of_span_from_other_framework(self): ) +class MultiMapping(Mapping): + + def __init__(self, *items: Tuple[str, str]): + self._items = items + + def __len__(self): + return len(self._items) + + def __getitem__(self, __key): + raise NotImplementedError("use .items() instead") + + def __iter__(self): + raise NotImplementedError("use .items() instead") + + def items(self): + return self._items + + @patch.dict( "os.environ", { @@ -583,13 +602,15 @@ def _create_app(): @app.get("/foobar") async def _(): - headers = { - "custom-test-header-1": "test-header-value-1", - "custom-test-header-2": "test-header-value-2", - "my-custom-regex-header-1": "my-custom-regex-value-1,my-custom-regex-value-2", - "My-Custom-Regex-Header-2": "my-custom-regex-value-3,my-custom-regex-value-4", - "My-Secret-Header": "My Secret Value", - } + headers = MultiMapping( + ("custom-test-header-1", "test-header-value-1"), + ("custom-test-header-2", "test-header-value-2"), + ("my-custom-regex-header-1", "my-custom-regex-value-1"), + ("my-custom-regex-header-1", "my-custom-regex-value-2"), + ("My-Custom-Regex-Header-2", "my-custom-regex-value-3"), + ("My-Custom-Regex-Header-2", "my-custom-regex-value-4"), + ("My-Secret-Header", "My Secret Value"), + ) content = {"message": "hello world"} return JSONResponse(content=content, headers=headers) @@ -665,10 +686,12 @@ def test_http_custom_response_headers_in_span_attributes(self): "test-header-value-2", ), "http.response.header.my_custom_regex_header_1": ( - "my-custom-regex-value-1,my-custom-regex-value-2", + "my-custom-regex-value-1", + "my-custom-regex-value-2", ), "http.response.header.my_custom_regex_header_2": ( - "my-custom-regex-value-3,my-custom-regex-value-4", + "my-custom-regex-value-3", + "my-custom-regex-value-4", ), "http.response.header.my_secret_header": ("[REDACTED]",), } diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index 4bb3608935..474a942a98 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -110,10 +110,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A The name of the added span attribute will follow the format ``http.request.header.`` where ```` is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -single item list containing all the header values. +list containing the header values. For example: -``http.request.header.custom_request_header = [","]`` +``http.request.header.custom_request_header = ["", ""]`` Response headers **************** @@ -144,10 +144,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A The name of the added span attribute will follow the format ``http.response.header.`` where ```` is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -single item list containing all the header values. +list containing the header values. For example: -``http.response.header.custom_response_header = [","]`` +``http.response.header.custom_response_header = ["", ""]`` Sanitizing headers ****************** diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index e8a2cf2034..f5dacf0fff 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -14,6 +14,7 @@ from __future__ import annotations +from collections.abc import Mapping from os import environ from re import IGNORECASE as RE_IGNORECASE from re import compile as re_compile @@ -87,32 +88,32 @@ def sanitize_header_value(self, header: str, value: str) -> str: def sanitize_header_values( self, - headers: dict[str, str], + headers: Mapping[str, str | list[str]], header_regexes: list[str], normalize_function: Callable[[str], str], - ) -> dict[str, str]: - values: dict[str, str] = {} + ) -> dict[str, list[str]]: + values: dict[str, list[str]] = {} if header_regexes: header_regexes_compiled = re_compile( - "|".join("^" + i + "$" for i in header_regexes), + "|".join(header_regexes), RE_IGNORECASE, ) - for header_name in list( - filter( - header_regexes_compiled.match, - headers.keys(), - ) - ): - header_values = headers.get(header_name) - if header_values: + for header_name, header_value in headers.items(): + if header_regexes_compiled.fullmatch(header_name): key = normalize_function(header_name.lower()) - values[key] = [ - self.sanitize_header_value( - header=header_name, value=header_values - ) - ] + if isinstance(header_value, str): + values[key] = [ + self.sanitize_header_value( + header_name, header_value + ) + ] + else: + values[key] = [ + self.sanitize_header_value(header_name, value) + for value in header_value + ] return values From a166208616e7b84368dcfb8ebbfec875da3c7d96 Mon Sep 17 00:00:00 2001 From: Mathieu Pichette Date: Thu, 20 Jun 2024 15:51:28 -0700 Subject: [PATCH 058/335] confluent_kafka: extend instruments version declaration to include 2.4.0 (#2616) * confluent_kafka: update instruments version declaration to include 2.4.0 * Adjust CHANGELOG.md with actual PR number --------- Co-authored-by: Diego Hurtado --- CHANGELOG.md | 2 ++ docs-requirements.txt | 2 +- instrumentation/README.md | 2 +- .../pyproject.toml | 2 +- .../opentelemetry/instrumentation/confluent_kafka/package.py | 2 +- .../test-requirements.txt | 2 +- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 2 +- 7 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9b5478b65..d4fbe906aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2622](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2622)) - `opentelemetry-sdk-extension-aws` Add AwsXrayLambdaPropagator ([#2573](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2573)) +- `opentelemetry-instrumentation-confluent-kafka` Add support for version 2.4.0 of confluent_kafka + ([#2616](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2616)) ### Breaking changes diff --git a/docs-requirements.txt b/docs-requirements.txt index 6a822e44da..34ce74ca7a 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -27,7 +27,7 @@ botocore~=1.0 boto3~=1.0 cassandra-driver~=3.25 celery>=4.0 -confluent-kafka>= 1.8.2,<= 2.3.0 +confluent-kafka>= 1.8.2,<= 2.4.0 elasticsearch>=6.0,<9.0 flask~=2.0 falcon~=2.0 diff --git a/instrumentation/README.md b/instrumentation/README.md index 5dfed03e9a..682334db1a 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -14,7 +14,7 @@ | [opentelemetry-instrumentation-botocore](./opentelemetry-instrumentation-botocore) | botocore ~= 1.0 | No | experimental | [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | experimental | [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | experimental -| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.3.0 | No | experimental +| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.4.0 | No | experimental | [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | experimental | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index cac767986e..94a2497b36 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "confluent-kafka >= 1.8.2, <= 2.3.0", + "confluent-kafka >= 1.8.2, <= 2.4.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py index bbc900c1dd..6ebddd30ac 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py @@ -13,4 +13,4 @@ # limitations under the License. -_instruments = ("confluent-kafka >= 1.8.2, <= 2.3.0",) +_instruments = ("confluent-kafka >= 1.8.2, <= 2.4.0",) diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 1297185d4b..87387ded81 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -1,5 +1,5 @@ asgiref==3.7.2 -confluent-kafka==2.3.0 +confluent-kafka==2.4.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index ea8fa48046..3dfd97e0b2 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -65,7 +65,7 @@ "instrumentation": "opentelemetry-instrumentation-celery==0.47b0.dev", }, { - "library": "confluent-kafka >= 1.8.2, <= 2.3.0", + "library": "confluent-kafka >= 1.8.2, <= 2.4.0", "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.47b0.dev", }, { From 593f86fd043ace5e20d52df415b687f37229b484 Mon Sep 17 00:00:00 2001 From: shwejan raj <83217783+shwejanraj@users.noreply.github.com> Date: Sat, 22 Jun 2024 00:55:01 +0530 Subject: [PATCH 059/335] Adds NoOpTracerProvider test case for pymysql instrumentation (#2581) --- .../tests/test_pymysql_integration.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py index 587ebc1b53..6f8af5d8df 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py @@ -17,6 +17,7 @@ import pymysql import opentelemetry.instrumentation.pymysql +from opentelemetry import trace as trace_api from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor from opentelemetry.sdk import resources from opentelemetry.test.test_base import TestBase @@ -78,6 +79,20 @@ def test_custom_tracer_provider(self, mock_connect): self.assertIs(span.resource, resource) + @mock.patch("pymysql.connect") + # pylint: disable=unused-argument + def test_no_op_tracer_provider(self, mock_connect): + PyMySQLInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + cnx = pymysql.connect(database="test") + cursor = cnx.cursor() + query = "SELECT * FROM test" + cursor.execute(query) + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock.patch("pymysql.connect") # pylint: disable=unused-argument def test_instrument_connection(self, mock_connect): From 919b2c295f68963e2581d9a0d214fa18a2bf7059 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Sat, 22 Jun 2024 11:44:55 +0200 Subject: [PATCH 060/335] CHANGELOG: remove spurious backtick (#2628) Co-authored-by: Shalev Roda <65566801+shalevr@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4fbe906aa..d2b2c930b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2300](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2300)) - Rename AwsLambdaInstrumentor span attributes `faas.id` to `cloud.resource_id`, `faas.execution` to `faas.invocation_id` ([#2372](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2372)) -- Drop support for instrumenting elasticsearch client < 6` +- Drop support for instrumenting elasticsearch client < 6 ([#2422](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2422)) - `opentelemetry-instrumentation-wsgi` Add `http.method` to `span.name` ([#2425](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2425)) From 3d758a973c015f6b994e221d22a9b7e29b62adb7 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 24 Jun 2024 18:31:04 +0200 Subject: [PATCH 061/335] instrumentation/system-metrics: permit to use psutil 6.0 (#2630) --- CHANGELOG.md | 2 ++ .../opentelemetry-instrumentation-system-metrics/pyproject.toml | 2 +- .../test-requirements.txt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2b2c930b6..5ddb3f488b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) +- `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. + ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 07ba2faa20..8518ddc8db 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ dependencies = [ "opentelemetry-instrumentation == 0.47b0.dev", "opentelemetry-api ~= 1.11", - "psutil ~= 5.9", + "psutil >= 5.9.0, < 7", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index ddb98399cf..13573c65bd 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -4,7 +4,7 @@ importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 -psutil==5.9.8 +psutil==6.0.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 From ff17c79c160ecef2497c44219fed7d7f4617e8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 25 Jun 2024 13:54:48 -0300 Subject: [PATCH 062/335] Update contributing guide and remove test instructions from readme (#2632) --- CONTRIBUTING.md | 27 +++++++++++++++++++++------ README.md | 9 --------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1cc77b184a..6579774979 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,13 +60,13 @@ $ pip install tox You can run `tox` with the following arguments: -- `tox` to run all existing tox commands, including unit tests for all packages +* `tox` to run all existing tox commands, including unit tests for all packages under multiple Python versions -- `tox -e docs` to regenerate the API docs -- `tox -e py312-test-instrumentation-aiopg` to e.g. run the aiopg instrumentation unit tests under a specific +* `tox -e docs` to regenerate the API docs +* `tox -e py312-test-instrumentation-aiopg` to e.g. run the aiopg instrumentation unit tests under a specific Python version -- `tox -e spellcheck` to run a spellcheck on all the code -- `tox -e lint-some-package` to run lint checks on `some-package` +* `tox -e spellcheck` to run a spellcheck on all the code +* `tox -e lint-some-package` to run lint checks on `some-package` `black` and `isort` are executed when `tox -e lint` is run. The reported errors can be tedious to fix manually. An easier way to do so is: @@ -84,6 +84,7 @@ You can also configure it to run lint tools automatically before committing with ```console $ pre-commit install +``` See [`tox.ini`](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/tox.ini) @@ -161,6 +162,7 @@ Open a pull request against the main `opentelemetry-python-contrib` repo. * If the PR is not ready for review, please put `[WIP]` in the title, tag it as `work-in-progress`, or mark it as [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/). +* Make sure tests and lint are passing locally before requesting a review. * Make sure CLA is signed and CI is clear. ### How to Get PRs Reviewed @@ -216,13 +218,26 @@ For a deeper discussion, see: https://github.com/open-telemetry/opentelemetry-sp 2. Make sure you have `tox` installed. `pip install tox`. 3. Run `tox` without any arguments to run tests for all the packages. Read more about [tox](https://tox.readthedocs.io/en/latest/). +Some tests can be slow due to pre-steps that do dependencies installs. To help with that, you can run tox a first time, and after that run the tests using previous installed dependencies in toxdir as following: + +1. First time run (e.g., opentelemetry-instrumentation-aiopg) +```console +tox -e py312-test-instrumentation-aiopg +``` +2. Run tests again without pre-steps: +```console +.tox/py312-test-instrumentation-aiopg/bin/pytest instrumentation/opentelemetry-instrumentation-aiopg +``` + ### Testing against a different Core repo branch/commit Some of the tox targets install packages from the [OpenTelemetry Python Core Repository](https://github.com/open-telemetry/opentelemetry-python) via pip. The version of the packages installed defaults to the main branch in that repository when tox is run locally. It is possible to install packages tagged with a specific git commit hash by setting an environment variable before running tox as per the following example: +```sh CORE_REPO_SHA=c49ad57bfe35cfc69bfa863d74058ca9bec55fc3 tox +``` -The continuation integration overrides that environment variable with as per the configuration [here](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/2518a4ac07cb62ad6587dd8f6cbb5f8663a7e179/.github/workflows/test.yml#L9). +The continuous integration overrides that environment variable with as per the configuration [here](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/test.yml#L9). ## Style Guide diff --git a/README.md b/README.md index 133acf81f6..6c019239ae 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,6 @@ The Python auto-instrumentation libraries for [OpenTelemetry](https://openteleme * [Releasing](#releasing) * [Releasing a package as `1.0` stable](#releasing-a-package-as-10-stable) * [Contributing](#contributing) -* [Running Tests Locally](#running-tests-locally) * [Thanks to all the people who already contributed](#thanks-to-all-the-people-who-already-contributed) ## Installation @@ -143,14 +142,6 @@ Emeritus Maintainers: *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* -## Running Tests Locally - -1. Go to your Contrib repo directory. `cd ~/git/opentelemetry-python-contrib`. -2. Create a virtual env in your Contrib repo directory. `python3 -m venv my_test_venv`. -3. Activate your virtual env. `source my_test_venv/bin/activate`. -4. Make sure you have `tox` installed. `pip install tox`. -5. Run tests for a package. (e.g. `tox -e test-instrumentation-flask`.) - ### Thanks to all the people who already contributed From f531996f531f281e2861c10bf852f4d3d60518e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:34:04 -0300 Subject: [PATCH 063/335] fix util-http package (#2634) --- tox.ini | 5 +++++ util/opentelemetry-util-http/test-requirements.txt | 12 ++++++++++++ .../tests/test_sanitize_method.py | 4 ++-- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 util/opentelemetry-util-http/test-requirements.txt diff --git a/tox.ini b/tox.ini index 54d2354952..e18bdf6a6f 100644 --- a/tox.ini +++ b/tox.ini @@ -761,6 +761,11 @@ commands_pre = processor-baggage: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk processor-baggage: pip install -r {toxinidir}/processor/opentelemetry-processor-baggage/test-requirements.txt + http: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + http: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + http: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + http: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + http: pip install -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt http: pip install {toxinidir}/util/opentelemetry-util-http ; In order to get a health coverage report, diff --git a/util/opentelemetry-util-http/test-requirements.txt b/util/opentelemetry-util-http/test-requirements.txt new file mode 100644 index 0000000000..0e28bbdd05 --- /dev/null +++ b/util/opentelemetry-util-http/test-requirements.txt @@ -0,0 +1,12 @@ +asgiref==3.7.2 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +pytest-benchmark==4.0.0 +tomli==2.0.1 +typing_extensions==4.10.0 +-e opentelemetry-instrumentation \ No newline at end of file diff --git a/util/opentelemetry-util-http/tests/test_sanitize_method.py b/util/opentelemetry-util-http/tests/test_sanitize_method.py index b4095324a6..bd14d88ee5 100644 --- a/util/opentelemetry-util-http/tests/test_sanitize_method.py +++ b/util/opentelemetry-util-http/tests/test_sanitize_method.py @@ -32,7 +32,7 @@ def test_standard_method_lowercase(self): def test_nonstandard_method(self): method = sanitize_method("UNKNOWN") - self.assertEqual(method, "NONSTANDARD") + self.assertEqual(method, "_OTHER") @patch.dict( "os.environ", @@ -42,4 +42,4 @@ def test_nonstandard_method(self): ) def test_nonstandard_method_allowed(self): method = sanitize_method("UNKNOWN") - self.assertEqual(method, "NONSTANDARD") + self.assertEqual(method, "UNKNOWN") From 7f7c0f31feffa4297b9f27902e272d0ccbb62e2a Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 26 Jun 2024 21:35:11 +0200 Subject: [PATCH 064/335] Use python baseline for pylint (#2636) --- .pylintrc | 3 +++ CONTRIBUTING.md | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.pylintrc b/.pylintrc index 9f6c80faa9..39ea7b5d35 100644 --- a/.pylintrc +++ b/.pylintrc @@ -45,6 +45,9 @@ suggestion-mode=yes # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no +# Run python dependant checks considering the baseline version +py-version=3.8 + [MESSAGES CONTROL] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6579774979..f5a4913440 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -275,3 +275,24 @@ Below is a checklist of things to be mindful of when implementing a new instrume ## Expectations from contributors OpenTelemetry is an open source community, and as such, greatly encourages contributions from anyone interested in the project. With that being said, there is a certain level of expectation from contributors even after a pull request is merged, specifically pertaining to instrumentations. The OpenTelemetry Python community expects contributors to maintain a level of support and interest in the instrumentations they contribute. This is to ensure that the instrumentation does not become stale and still functions the way the original contributor intended. Some instrumentations also pertain to libraries that the current members of the community are not so familiar with, so it is necessary to rely on the expertise of the original contributing parties. + +## Updating supported Python versions + +### Bumping the Python baseline + +When updating the minimum supported Python version remember to: + +- Remove the version in `pyproject.toml` trove classifiers +- Remove the version from `tox.ini` +- Search for `sys.version_info` usage and remove code for unsupported versions +- Bump `py-version` in `.pylintrc` for Python version dependent checks + +### Adding support for a new Python release + +When adding support for a new Python release remember to: + +- Add the version in `tox.ini` +- Add the version in `pyproject.toml` trove classifiers +- Update github workflows accordingly; lint and benchmarks use the latest supported version +- Update `.pre-commit-config.yaml` +- Update tox examples in the documentation From 58a6d3a79c2ab33b80786216e8601e880858b9ab Mon Sep 17 00:00:00 2001 From: joshschltelus <144482830+joshschltelus@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:19:50 -0700 Subject: [PATCH 065/335] conflent-kafka: Proxy producer purge (#2638) --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/confluent_kafka/__init__.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ddb3f488b..f0fd2243dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2573](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2573)) - `opentelemetry-instrumentation-confluent-kafka` Add support for version 2.4.0 of confluent_kafka ([#2616](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2616)) +- `opentelemetry-instrumentation-confluent-kafka` Add support for produce purge + ([#2638](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2638)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index 30181d39c2..45d45ccb63 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -156,6 +156,9 @@ def flush(self, timeout=-1): def poll(self, timeout=-1): return self._producer.poll(timeout) + def purge(self, in_queue=True, in_flight=True, blocking=True): + self._producer.purge(in_queue, in_flight, blocking) + def produce( self, topic, value=None, *args, **kwargs ): # pylint: disable=keyword-arg-before-vararg From 529178d9ae1eb721c2402cd7a09c96e7d76bc04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:35:10 -0300 Subject: [PATCH 066/335] Fix wrong unit in Flask new semconv test (#2645) --- .../tests/test_programmatic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index f50d3245a0..3f47eebcca 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -497,7 +497,7 @@ def test_flask_metrics_new_semconv(self): self.client.get("/hello/123") self.client.get("/hello/321") self.client.get("/hello/756") - duration = max(round((default_timer() - start) * 1000), 0) + duration_s = max(default_timer() - start, 0) metrics_list = self.memory_metrics_reader.get_metrics_data() number_data_point_seen = False histogram_data_point_seen = False @@ -514,7 +514,7 @@ def test_flask_metrics_new_semconv(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 3) self.assertAlmostEqual( - duration, point.sum, delta=10 + duration_s, point.sum, places=2 ) histogram_data_point_seen = True if isinstance(point, NumberDataPoint): From a29242f49386c097defce500b138dc00f06ce300 Mon Sep 17 00:00:00 2001 From: Radoslav Kirilov Date: Tue, 2 Jul 2024 18:21:15 +0300 Subject: [PATCH 067/335] fix(async-io): instrumented `asyncio.wait_for` properly raises `asyncio.TimeoutError` (#2637) --- CHANGELOG.md | 2 ++ .../instrumentation/asyncio/__init__.py | 3 +++ .../tests/test_asyncio_wait.py | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0fd2243dd..d43e789bd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- `opentelemetry-instrumentation-asyncio` instrumented `asyncio.wait_for` properly raises `asyncio.TimeoutError` as expected + ([#2637](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2637)) - `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) - `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index fc1b535270..f5f0d34c4f 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -280,8 +280,11 @@ async def trace_coroutine(self, coro): # CancelledError is raised when a coroutine is cancelled # before it has a chance to run. We don't want to record # this as an error. + # Still it needs to be raised in order for `asyncio.wait_for` + # to properly work with timeout and raise accordingly `asyncio.TimeoutError` except asyncio.CancelledError: attr["state"] = "cancelled" + raise except Exception as exc: exception = exc state = determine_state(exception) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_wait.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_wait.py index 77064aeafa..312f035d36 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_wait.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_wait.py @@ -68,6 +68,19 @@ async def main(): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) + def test_asyncio_wait_for_with_timeout(self): + expected_timeout_error = None + + async def main(): + nonlocal expected_timeout_error + try: + await asyncio.wait_for(async_func(), 0.01) + except asyncio.TimeoutError as timeout_error: + expected_timeout_error = timeout_error + + asyncio.run(main()) + self.assertNotEqual(expected_timeout_error, None) + def test_asyncio_as_completed(self): async def main(): if sys.version_info >= (3, 11): From df3415b0ddc77e381b7b9da9458b79892650e7b7 Mon Sep 17 00:00:00 2001 From: joshschltelus <144482830+joshschltelus@users.noreply.github.com> Date: Tue, 2 Jul 2024 08:43:32 -0700 Subject: [PATCH 068/335] Confluent Kafka: Ensure consume span is ended when consumer is closed (#2640) --- CHANGELOG.md | 2 + .../confluent_kafka/__init__.py | 24 ++++++++++++ .../tests/test_instrumentation.py | 37 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d43e789bd8..c4a42d1c36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) - Reference symbols from generated semantic conventions ([#2611](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2611)) +- `opentelemetry-instrumentation-confluent-kafka` Confluent Kafka: Ensure consume span is ended when consumer is closed + ([#2640](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2640)) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index 45d45ccb63..3d1cc79c93 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -144,6 +144,10 @@ def consume( ): # pylint: disable=useless-super-delegation return super().consume(*args, **kwargs) + # This method is deliberately implemented in order to allow wrapt to wrap this function + def close(self): # pylint: disable=useless-super-delegation + return super().close() + class ProxiedProducer(Producer): def __init__(self, producer: Producer, tracer: Tracer): @@ -181,6 +185,11 @@ def __init__(self, consumer: Consumer, tracer: Tracer): self._current_consume_span = None self._current_context_token = None + def close(self): + return ConfluentKafkaInstrumentor.wrap_close( + self._consumer.close, self + ) + def committed(self, partitions, timeout=-1): return self._consumer.committed(partitions, timeout) @@ -303,6 +312,9 @@ def _inner_wrap_consume(func, instance, args, kwargs): func, instance, self._tracer, args, kwargs ) + def _inner_wrap_close(func, instance): + return ConfluentKafkaInstrumentor.wrap_close(func, instance) + wrapt.wrap_function_wrapper( AutoInstrumentedProducer, "produce", @@ -321,6 +333,12 @@ def _inner_wrap_consume(func, instance, args, kwargs): _inner_wrap_consume, ) + wrapt.wrap_function_wrapper( + AutoInstrumentedConsumer, + "close", + _inner_wrap_close, + ) + def _uninstrument(self, **kwargs): confluent_kafka.Producer = self._original_kafka_producer confluent_kafka.Consumer = self._original_kafka_consumer @@ -403,3 +421,9 @@ def wrap_consume(func, instance, tracer, args, kwargs): ) return records + + @staticmethod + def wrap_close(func, instance): + if instance._current_consume_span: + _end_current_consume_span(instance) + func() diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py index 205de27733..27653d6777 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py @@ -237,7 +237,44 @@ def test_consume(self) -> None: span_list = self.memory_exporter.get_finished_spans() self._compare_spans(span_list, expected_spans) + def test_close(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + mocked_messages = [ + MockedMessage("topic-a", 0, 0, []), + ] + expected_spans = [ + {"name": "recv", "attributes": {}}, + { + "name": "topic-a process", + "attributes": { + SpanAttributes.MESSAGING_OPERATION: "process", + SpanAttributes.MESSAGING_KAFKA_PARTITION: 0, + SpanAttributes.MESSAGING_SYSTEM: "kafka", + SpanAttributes.MESSAGING_DESTINATION: "topic-a", + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, + SpanAttributes.MESSAGING_MESSAGE_ID: "topic-a.0.0", + }, + }, + ] + + consumer = MockConsumer( + mocked_messages, + { + "bootstrap.servers": "localhost:29092", + "group.id": "mygroup", + "auto.offset.reset": "earliest", + }, + ) + self.memory_exporter.clear() + consumer = instrumentation.instrument_consumer(consumer) + consumer.poll() + consumer.close() + + span_list = self.memory_exporter.get_finished_spans() + self._compare_spans(span_list, expected_spans) + def _compare_spans(self, spans, expected_spans): + self.assertEqual(len(spans), len(expected_spans)) for span, expected_span in zip(spans, expected_spans): self.assertEqual(expected_span["name"], span.name) for attribute_key, expected_attribute_value in expected_span[ From 90211489a3e7c094d4084166b28f504c82a1315c Mon Sep 17 00:00:00 2001 From: Hollis Wu Date: Tue, 2 Jul 2024 12:05:41 -0400 Subject: [PATCH 069/335] Handle empty statement in psycopg instrumentation (#2644) --- CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/psycopg/__init__.py | 3 ++- .../tests/test_psycopg_integration.py | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a42d1c36..f597d64da9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) - Reference symbols from generated semantic conventions ([#2611](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2611)) +- `opentelemetry-instrumentation-psycopg` Bugfix: Handle empty statement. + ([#2644](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2644)) - `opentelemetry-instrumentation-confluent-kafka` Confluent Kafka: Ensure consume span is ended when consumer is closed ([#2640](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2640)) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py index 5d7054151a..4f61713b29 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py @@ -269,7 +269,8 @@ def get_operation_name(self, cursor, args): if isinstance(statement, Composed): statement = statement.as_string(cursor) - if isinstance(statement, str): + # `statement` can be empty string. See #2643 + if statement and isinstance(statement, str): # Strip leading comments so we get the operation name. return self._leading_comment_remover.sub("", statement).split()[0] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py index 5a5b39d80b..dc9969ba8c 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py @@ -245,14 +245,18 @@ def test_span_name(self): cursor.execute("/* leading comment */ query") cursor.execute("/* leading comment */ query /* trailing comment */") cursor.execute("query /* trailing comment */") + cursor.execute("") + cursor.execute("--") spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 6) + self.assertEqual(len(spans_list), 8) self.assertEqual(spans_list[0].name, "Test") self.assertEqual(spans_list[1].name, "multi") self.assertEqual(spans_list[2].name, "tab") self.assertEqual(spans_list[3].name, "query") self.assertEqual(spans_list[4].name, "query") self.assertEqual(spans_list[5].name, "query") + self.assertEqual(spans_list[6].name, "postgresql") + self.assertEqual(spans_list[7].name, "--") # pylint: disable=unused-argument def test_not_recording(self): From 77749225b7d19b604e564f277c38f9ff90326eec Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 2 Jul 2024 20:32:39 +0200 Subject: [PATCH 070/335] opentelemetry-processor-baggage: silence ruff warning (#2653) --- .../src/opentelemetry/processor/baggage/processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py index d14cf3a7e6..7e09e591e0 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py @@ -23,7 +23,7 @@ BaggageKeyPredicateT = Callable[[str], bool] # A BaggageKeyPredicate that always returns True, allowing all baggage keys to be added to spans -ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True +ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True # noqa: E731 class BaggageSpanProcessor(SpanProcessor): From b16394b2027b345c1e95b1686ee65eeea51d492b Mon Sep 17 00:00:00 2001 From: Eddie Bracho Date: Tue, 2 Jul 2024 11:41:55 -0700 Subject: [PATCH 071/335] [opentelemetry-instrumentation-django] Handle exceptions from request/response hooks (#2153) --- CHANGELOG.md | 5 +++- .../django/middleware/otel_middleware.py | 22 +++++++++++----- .../tests/test_middleware.py | 26 +++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f597d64da9..50f290300c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- `opentelemetry-instrumentation-django` Handle exceptions from request/response hooks + ([#2153](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2153)) - `opentelemetry-instrumentation-asyncio` instrumented `asyncio.wait_for` properly raises `asyncio.TimeoutError` as expected ([#2637](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2637)) - `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. @@ -151,7 +153,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2136](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2136)) - `opentelemetry-resource-detector-azure` Suppress instrumentation for `urllib` call ([#2178](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2178)) -- AwsLambdaInstrumentor handles and re-raises function exception ([#2245](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2245)) +- AwsLambdaInstrumentor handles and re-raises function exception + ([#2245](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2245)) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 1b747fd2c0..6b64865ef7 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -187,6 +187,7 @@ def _get_span_name(request): return request.method # pylint: disable=too-many-locals + # pylint: disable=too-many-branches def process_request(self, request): # request.META is a dictionary containing all available HTTP headers # Read more about request.META here: @@ -286,9 +287,14 @@ def process_request(self, request): request.META[self._environ_token] = token if _DjangoMiddleware._otel_request_hook: - _DjangoMiddleware._otel_request_hook( # pylint: disable=not-callable - span, request - ) + try: + _DjangoMiddleware._otel_request_hook( # pylint: disable=not-callable + span, request + ) + except Exception: # pylint: disable=broad-exception-caught + # Raising an exception here would leak the request span since process_response + # would not be called. Log the exception instead. + _logger.exception("Exception raised by request_hook") # pylint: disable=unused-argument def process_view(self, request, view_func, *args, **kwargs): @@ -385,10 +391,14 @@ def process_response(self, request, response): # record any exceptions raised while processing the request exception = request.META.pop(self._environ_exception_key, None) + if _DjangoMiddleware._otel_response_hook: - _DjangoMiddleware._otel_response_hook( # pylint: disable=not-callable - span, request, response - ) + try: + _DjangoMiddleware._otel_response_hook( # pylint: disable=not-callable + span, request, response + ) + except Exception: # pylint: disable=broad-exception-caught + _logger.exception("Exception raised by response_hook") if exception: activation.__exit__( diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index 63af1e6b86..c6b0568ef8 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -392,6 +392,32 @@ def response_hook(span, request, response): self.assertIsInstance(response_hook_args[2], HttpResponse) self.assertEqual(response_hook_args[2], response) + def test_request_hook_exception(self): + def request_hook(span, request): + # pylint: disable=broad-exception-raised + raise Exception("request hook exception") + + _DjangoMiddleware._otel_request_hook = request_hook + Client().get("/span_name/1234/") + _DjangoMiddleware._otel_request_hook = None + + # ensure that span ended + finished_spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(finished_spans), 1) + + def test_response_hook_exception(self): + def response_hook(span, request, response): + # pylint: disable=broad-exception-raised + raise Exception("response hook exception") + + _DjangoMiddleware._otel_response_hook = response_hook + Client().get("/span_name/1234/") + _DjangoMiddleware._otel_response_hook = None + + # ensure that span ended + finished_spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(finished_spans), 1) + def test_trace_parent(self): id_generator = RandomIdGenerator() trace_id = format_trace_id(id_generator.generate_trace_id()) From ef4bc9f9b479a32bf42a9661dc04e07e32b091c3 Mon Sep 17 00:00:00 2001 From: dhofstetter Date: Wed, 3 Jul 2024 19:28:54 +0200 Subject: [PATCH 072/335] fix(opentelemetry-instrumentation-asgi): Correct http.url attribute generation (#2477) --- CHANGELOG.md | 4 + .../instrumentation/asgi/__init__.py | 8 +- .../tests/test_fastapi_instrumentation.py | 694 +++++++----------- ..._fastapi_instrumentation_custom_headers.py | 381 ++++++++++ .../test_fastapi_instrumentation_wrapped.py | 64 ++ .../tests/test_starlette_instrumentation.py | 180 ++++- 6 files changed, 907 insertions(+), 424 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py create mode 100644 instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_wrapped.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 50f290300c..8fd9235c09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) - `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) +- `opentelemetry-instrumentation-asgi` Fix generation of `http.target` and `http.url` attributes for ASGI apps + using sub apps + ([#2477](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2477)) + ### Added diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index f24160fcb6..b3cd9025c7 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -367,7 +367,13 @@ def get_host_port_url_tuple(scope): server = scope.get("server") or ["0.0.0.0", 80] port = server[1] server_host = server[0] + (":" + str(port) if str(port) != "80" else "") - full_path = scope.get("root_path", "") + scope.get("path", "") + # using the scope path is enough, see: + # - https://asgi.readthedocs.io/en/latest/specs/www.html#http-connection-scope (see: root_path and path) + # - https://asgi.readthedocs.io/en/latest/specs/www.html#wsgi-compatibility (see: PATH_INFO) + # PATH_INFO can be derived by stripping root_path from path + # -> that means that the path should contain the root_path already, so prefixing it again is not necessary + # - https://wsgi.readthedocs.io/en/latest/definitions.html#envvar-PATH_INFO + full_path = scope.get("path", "") http_url = scope.get("scheme", "http") + "://" + server_host + full_path return server_host, port, http_url diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 26d9e743a8..0ad63164d5 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -12,18 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. import unittest -from collections.abc import Mapping from timeit import default_timer -from typing import Tuple from unittest.mock import patch import fastapi from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware -from fastapi.responses import JSONResponse from fastapi.testclient import TestClient import opentelemetry.instrumentation.fastapi as otel_fastapi -from opentelemetry import trace from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.sdk.metrics.export import ( HistogramDataPoint, @@ -31,12 +27,8 @@ ) from opentelemetry.sdk.resources import Resource from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.test.globals_test import reset_trace_globals from opentelemetry.test.test_base import TestBase from opentelemetry.util.http import ( - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, _active_requests_count_attrs, _duration_attrs, get_excluded_urls, @@ -62,7 +54,7 @@ } -class TestFastAPIManualInstrumentation(TestBase): +class TestBaseFastAPI(TestBase): def _create_app(self): app = self._create_fastapi_app() self._instrumentor.instrument_app( @@ -85,6 +77,15 @@ def _create_app_explicit_excluded_urls(self): ) return app + @classmethod + def setUpClass(cls): + if cls is TestBaseFastAPI: + raise unittest.SkipTest( + f"{cls.__name__} is an abstract base class" + ) + + super(TestBaseFastAPI, cls).setUpClass() + def setUp(self): super().setUp() self.env_patch = patch.dict( @@ -110,6 +111,155 @@ def tearDown(self): self._instrumentor.uninstrument() self._instrumentor.uninstrument_app(self._app) + @staticmethod + def _create_fastapi_app(): + app = fastapi.FastAPI() + sub_app = fastapi.FastAPI() + + @sub_app.get("/home") + async def _(): + return {"message": "sub hi"} + + @app.get("/foobar") + async def _(): + return {"message": "hello world"} + + @app.get("/user/{username}") + async def _(username: str): + return {"message": username} + + @app.get("/exclude/{param}") + async def _(param: str): + return {"message": param} + + @app.get("/healthzz") + async def _(): + return {"message": "ok"} + + app.mount("/sub", app=sub_app) + + return app + + +class TestBaseManualFastAPI(TestBaseFastAPI): + + @classmethod + def setUpClass(cls): + if cls is TestBaseManualFastAPI: + raise unittest.SkipTest( + f"{cls.__name__} is an abstract base class" + ) + + super(TestBaseManualFastAPI, cls).setUpClass() + + def test_sub_app_fastapi_call(self): + """ + This test is to ensure that a span in case of a sub app targeted contains the correct server url + + As this test case covers manual instrumentation, we won't see any additional spans for the sub app. + In this case all generated spans might suffice the requirements for the attributes already + (as the testcase is not setting a root_path for the outer app here) + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 3) + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + self.assertIn("GET /sub", span.name) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # We expect only one span to have the HTTP attributes set (the SERVER span from the app itself) + # the sub app is not instrumented with manual instrumentation tests. + self.assertEqual(1, len(spans_with_http_attributes)) + + for span in spans_with_http_attributes: + self.assertEqual( + "/sub/home", span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "https://testserver:443/sub/home", + span.attributes[SpanAttributes.HTTP_URL], + ) + + +class TestBaseAutoFastAPI(TestBaseFastAPI): + + @classmethod + def setUpClass(cls): + if cls is TestBaseAutoFastAPI: + raise unittest.SkipTest( + f"{cls.__name__} is an abstract base class" + ) + + super(TestBaseAutoFastAPI, cls).setUpClass() + + def test_sub_app_fastapi_call(self): + """ + This test is to ensure that a span in case of a sub app targeted contains the correct server url + + As this test case covers auto instrumentation, we will see additional spans for the sub app. + In this case all generated spans might suffice the requirements for the attributes already + (as the testcase is not setting a root_path for the outer app here) + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 6) + + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + # -> the outer app is not aware of the sub_apps internal routes + sub_in = "GET /sub" in span.name + # The sub app spans are named GET /home as from the sub app perspective the request targets /home + # -> the sub app is technically not aware of the /sub prefix + home_in = "GET /home" in span.name + + # We expect the spans to be either from the outer app or the sub app + self.assertTrue( + sub_in or home_in, + f"Span {span.name} does not have /sub or /home in its name", + ) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # We now expect spans with attributes from both the app and its sub app + self.assertEqual(2, len(spans_with_http_attributes)) + + for span in spans_with_http_attributes: + self.assertEqual( + "/sub/home", span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "https://testserver:443/sub/home", + span.attributes[SpanAttributes.HTTP_URL], + ) + + +class TestFastAPIManualInstrumentation(TestBaseManualFastAPI): def test_instrument_app_with_instrument(self): if not isinstance(self, TestAutoInstrumentation): self._instrumentor.instrument() @@ -322,6 +472,11 @@ def test_metric_uninstrument(self): @staticmethod def _create_fastapi_app(): app = fastapi.FastAPI() + sub_app = fastapi.FastAPI() + + @sub_app.get("/home") + async def _(): + return {"message": "sub hi"} @app.get("/foobar") async def _(): @@ -339,10 +494,12 @@ async def _(param: str): async def _(): return {"message": "ok"} + app.mount("/sub", app=sub_app) + return app -class TestFastAPIManualInstrumentationHooks(TestFastAPIManualInstrumentation): +class TestFastAPIManualInstrumentationHooks(TestBaseManualFastAPI): _server_request_hook = None _client_request_hook = None _client_response_hook = None @@ -392,7 +549,7 @@ def client_response_hook(send_span, scope, message): ) -class TestAutoInstrumentation(TestFastAPIManualInstrumentation): +class TestAutoInstrumentation(TestBaseAutoFastAPI): """Test the auto-instrumented variant Extending the manual instrumentation as most test cases apply @@ -453,8 +610,60 @@ def tearDown(self): self._instrumentor.uninstrument() super().tearDown() + def test_sub_app_fastapi_call(self): + """ + !!! Attention: we need to override this testcase for the auto-instrumented variant + The reason is, that with auto instrumentation, the sub app is instrumented as well + and therefore we would see the spans for the sub app as well + + This test is to ensure that a span in case of a sub app targeted contains the correct server url + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 6) + + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + # -> the outer app is not aware of the sub_apps internal routes + sub_in = "GET /sub" in span.name + # The sub app spans are named GET /home as from the sub app perspective the request targets /home + # -> the sub app is technically not aware of the /sub prefix + home_in = "GET /home" in span.name + + # We expect the spans to be either from the outer app or the sub app + self.assertTrue( + sub_in or home_in, + f"Span {span.name} does not have /sub or /home in its name", + ) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # We now expect spans with attributes from both the app and its sub app + self.assertEqual(2, len(spans_with_http_attributes)) + + for span in spans_with_http_attributes: + self.assertEqual( + "/sub/home", span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "https://testserver:443/sub/home", + span.attributes[SpanAttributes.HTTP_URL], + ) + -class TestAutoInstrumentationHooks(TestFastAPIManualInstrumentationHooks): +class TestAutoInstrumentationHooks(TestBaseAutoFastAPI): """ Test the auto-instrumented variant for request and response hooks @@ -494,6 +703,58 @@ def tearDown(self): self._instrumentor.uninstrument() super().tearDown() + def test_sub_app_fastapi_call(self): + """ + !!! Attention: we need to override this testcase for the auto-instrumented variant + The reason is, that with auto instrumentation, the sub app is instrumented as well + and therefore we would see the spans for the sub app as well + + This test is to ensure that a span in case of a sub app targeted contains the correct server url + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 6) + + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + # -> the outer app is not aware of the sub_apps internal routes + sub_in = "GET /sub" in span.name + # The sub app spans are named GET /home as from the sub app perspective the request targets /home + # -> the sub app is technically not aware of the /sub prefix + home_in = "GET /home" in span.name + + # We expect the spans to be either from the outer app or the sub app + self.assertTrue( + sub_in or home_in, + f"Span {span.name} does not have /sub or /home in its name", + ) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # We now expect spans with attributes from both the app and its sub app + self.assertEqual(2, len(spans_with_http_attributes)) + + for span in spans_with_http_attributes: + self.assertEqual( + "/sub/home", span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "https://testserver:443/sub/home", + span.attributes[SpanAttributes.HTTP_URL], + ) + class TestAutoInstrumentationLogic(unittest.TestCase): def test_instrumentation(self): @@ -511,412 +772,3 @@ def test_instrumentation(self): should_be_original = fastapi.FastAPI self.assertIs(original, should_be_original) - - -class TestWrappedApplication(TestBase): - def setUp(self): - super().setUp() - - self.app = fastapi.FastAPI() - - @self.app.get("/foobar") - async def _(): - return {"message": "hello world"} - - otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) - self.client = TestClient(self.app) - self.tracer = self.tracer_provider.get_tracer(__name__) - - def tearDown(self) -> None: - super().tearDown() - with self.disable_logging(): - otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) - - def test_mark_span_internal_in_presence_of_span_from_other_framework(self): - with self.tracer.start_as_current_span( - "test", kind=trace.SpanKind.SERVER - ) as parent_span: - resp = self.client.get("/foobar") - self.assertEqual(200, resp.status_code) - - span_list = self.memory_exporter.get_finished_spans() - for span in span_list: - print(str(span.__class__) + ": " + str(span.__dict__)) - - # there should be 4 spans - single SERVER "test" and three INTERNAL "FastAPI" - self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind) - self.assertEqual(trace.SpanKind.INTERNAL, span_list[1].kind) - # main INTERNAL span - child of test - self.assertEqual(trace.SpanKind.INTERNAL, span_list[2].kind) - self.assertEqual( - parent_span.context.span_id, span_list[2].parent.span_id - ) - # SERVER "test" - self.assertEqual(trace.SpanKind.SERVER, span_list[3].kind) - self.assertEqual( - parent_span.context.span_id, span_list[3].context.span_id - ) - - -class MultiMapping(Mapping): - - def __init__(self, *items: Tuple[str, str]): - self._items = items - - def __len__(self): - return len(self._items) - - def __getitem__(self, __key): - raise NotImplementedError("use .items() instead") - - def __iter__(self): - raise NotImplementedError("use .items() instead") - - def items(self): - return self._items - - -@patch.dict( - "os.environ", - { - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*", - }, -) -class TestHTTPAppWithCustomHeaders(TestBase): - def setUp(self): - super().setUp() - self.app = self._create_app() - otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) - self.client = TestClient(self.app) - - def tearDown(self) -> None: - super().tearDown() - with self.disable_logging(): - otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) - - @staticmethod - def _create_app(): - app = fastapi.FastAPI() - - @app.get("/foobar") - async def _(): - headers = MultiMapping( - ("custom-test-header-1", "test-header-value-1"), - ("custom-test-header-2", "test-header-value-2"), - ("my-custom-regex-header-1", "my-custom-regex-value-1"), - ("my-custom-regex-header-1", "my-custom-regex-value-2"), - ("My-Custom-Regex-Header-2", "my-custom-regex-value-3"), - ("My-Custom-Regex-Header-2", "my-custom-regex-value-4"), - ("My-Secret-Header", "My Secret Value"), - ) - content = {"message": "hello world"} - return JSONResponse(content=content, headers=headers) - - return app - - def test_http_custom_request_headers_in_span_attributes(self): - expected = { - "http.request.header.custom_test_header_1": ( - "test-header-value-1", - ), - "http.request.header.custom_test_header_2": ( - "test-header-value-2", - ), - "http.request.header.regex_test_header_1": ("Regex Test Value 1",), - "http.request.header.regex_test_header_2": ( - "RegexTestValue2,RegexTestValue3", - ), - "http.request.header.my_secret_header": ("[REDACTED]",), - } - resp = self.client.get( - "/foobar", - headers={ - "custom-test-header-1": "test-header-value-1", - "custom-test-header-2": "test-header-value-2", - "Regex-Test-Header-1": "Regex Test Value 1", - "regex-test-header-2": "RegexTestValue2,RegexTestValue3", - "My-Secret-Header": "My Secret Value", - }, - ) - self.assertEqual(200, resp.status_code) - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 3) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - self.assertSpanHasAttributes(server_span, expected) - - def test_http_custom_request_headers_not_in_span_attributes(self): - not_expected = { - "http.request.header.custom_test_header_3": ( - "test-header-value-3", - ), - } - resp = self.client.get( - "/foobar", - headers={ - "custom-test-header-1": "test-header-value-1", - "custom-test-header-2": "test-header-value-2", - "Regex-Test-Header-1": "Regex Test Value 1", - "regex-test-header-2": "RegexTestValue2,RegexTestValue3", - "My-Secret-Header": "My Secret Value", - }, - ) - self.assertEqual(200, resp.status_code) - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 3) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - for key, _ in not_expected.items(): - self.assertNotIn(key, server_span.attributes) - - def test_http_custom_response_headers_in_span_attributes(self): - expected = { - "http.response.header.custom_test_header_1": ( - "test-header-value-1", - ), - "http.response.header.custom_test_header_2": ( - "test-header-value-2", - ), - "http.response.header.my_custom_regex_header_1": ( - "my-custom-regex-value-1", - "my-custom-regex-value-2", - ), - "http.response.header.my_custom_regex_header_2": ( - "my-custom-regex-value-3", - "my-custom-regex-value-4", - ), - "http.response.header.my_secret_header": ("[REDACTED]",), - } - resp = self.client.get("/foobar") - self.assertEqual(200, resp.status_code) - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 3) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - self.assertSpanHasAttributes(server_span, expected) - - def test_http_custom_response_headers_not_in_span_attributes(self): - not_expected = { - "http.response.header.custom_test_header_3": ( - "test-header-value-3", - ), - } - resp = self.client.get("/foobar") - self.assertEqual(200, resp.status_code) - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 3) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - for key, _ in not_expected.items(): - self.assertNotIn(key, server_span.attributes) - - -@patch.dict( - "os.environ", - { - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*", - }, -) -class TestWebSocketAppWithCustomHeaders(TestBase): - def setUp(self): - super().setUp() - self.app = self._create_app() - otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) - self.client = TestClient(self.app) - - def tearDown(self) -> None: - super().tearDown() - with self.disable_logging(): - otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) - - @staticmethod - def _create_app(): - app = fastapi.FastAPI() - - @app.websocket("/foobar_web") - async def _(websocket: fastapi.WebSocket): - message = await websocket.receive() - if message.get("type") == "websocket.connect": - await websocket.send( - { - "type": "websocket.accept", - "headers": [ - (b"custom-test-header-1", b"test-header-value-1"), - (b"custom-test-header-2", b"test-header-value-2"), - (b"Regex-Test-Header-1", b"Regex Test Value 1"), - ( - b"regex-test-header-2", - b"RegexTestValue2,RegexTestValue3", - ), - (b"My-Secret-Header", b"My Secret Value"), - ], - } - ) - await websocket.send_json({"message": "hello world"}) - await websocket.close() - if message.get("type") == "websocket.disconnect": - pass - - return app - - def test_web_socket_custom_request_headers_in_span_attributes(self): - expected = { - "http.request.header.custom_test_header_1": ( - "test-header-value-1", - ), - "http.request.header.custom_test_header_2": ( - "test-header-value-2", - ), - } - - with self.client.websocket_connect( - "/foobar_web", - headers={ - "custom-test-header-1": "test-header-value-1", - "custom-test-header-2": "test-header-value-2", - }, - ) as websocket: - data = websocket.receive_json() - self.assertEqual(data, {"message": "hello world"}) - - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 5) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - self.assertSpanHasAttributes(server_span, expected) - - @patch.dict( - "os.environ", - { - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", - }, - ) - def test_web_socket_custom_request_headers_not_in_span_attributes(self): - not_expected = { - "http.request.header.custom_test_header_3": ( - "test-header-value-3", - ), - } - - with self.client.websocket_connect( - "/foobar_web", - headers={ - "custom-test-header-1": "test-header-value-1", - "custom-test-header-2": "test-header-value-2", - }, - ) as websocket: - data = websocket.receive_json() - self.assertEqual(data, {"message": "hello world"}) - - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 5) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - for key, _ in not_expected.items(): - self.assertNotIn(key, server_span.attributes) - - def test_web_socket_custom_response_headers_in_span_attributes(self): - expected = { - "http.response.header.custom_test_header_1": ( - "test-header-value-1", - ), - "http.response.header.custom_test_header_2": ( - "test-header-value-2", - ), - } - - with self.client.websocket_connect("/foobar_web") as websocket: - data = websocket.receive_json() - self.assertEqual(data, {"message": "hello world"}) - - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 5) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - self.assertSpanHasAttributes(server_span, expected) - - def test_web_socket_custom_response_headers_not_in_span_attributes(self): - not_expected = { - "http.response.header.custom_test_header_3": ( - "test-header-value-3", - ), - } - - with self.client.websocket_connect("/foobar_web") as websocket: - data = websocket.receive_json() - self.assertEqual(data, {"message": "hello world"}) - - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 5) - - server_span = [ - span for span in span_list if span.kind == trace.SpanKind.SERVER - ][0] - - for key, _ in not_expected.items(): - self.assertNotIn(key, server_span.attributes) - - -@patch.dict( - "os.environ", - { - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3", - }, -) -class TestNonRecordingSpanWithCustomHeaders(TestBase): - def setUp(self): - super().setUp() - self.app = fastapi.FastAPI() - - @self.app.get("/foobar") - async def _(): - return {"message": "hello world"} - - reset_trace_globals() - tracer_provider = trace.NoOpTracerProvider() - trace.set_tracer_provider(tracer_provider=tracer_provider) - - self._instrumentor = otel_fastapi.FastAPIInstrumentor() - self._instrumentor.instrument_app(self.app) - self.client = TestClient(self.app) - - def tearDown(self) -> None: - super().tearDown() - with self.disable_logging(): - self._instrumentor.uninstrument_app(self.app) - - def test_custom_header_not_present_in_non_recording_span(self): - resp = self.client.get( - "/foobar", - headers={ - "custom-test-header-1": "test-header-value-1", - }, - ) - self.assertEqual(200, resp.status_code) - span_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(span_list), 0) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py new file mode 100644 index 0000000000..e7adca735c --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py @@ -0,0 +1,381 @@ +from collections.abc import Mapping +from typing import Tuple +from unittest.mock import patch + +import fastapi +from starlette.responses import JSONResponse +from starlette.testclient import TestClient + +import opentelemetry.instrumentation.fastapi as otel_fastapi +from opentelemetry import trace +from opentelemetry.test.globals_test import reset_trace_globals +from opentelemetry.test.test_base import TestBase +from opentelemetry.util.http import ( + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, +) + + +class MultiMapping(Mapping): + + def __init__(self, *items: Tuple[str, str]): + self._items = items + + def __len__(self): + return len(self._items) + + def __getitem__(self, __key): + raise NotImplementedError("use .items() instead") + + def __iter__(self): + raise NotImplementedError("use .items() instead") + + def items(self): + return self._items + + +@patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*", + }, +) +class TestHTTPAppWithCustomHeaders(TestBase): + def setUp(self): + super().setUp() + self.app = self._create_app() + otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) + self.client = TestClient(self.app) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) + + @staticmethod + def _create_app(): + app = fastapi.FastAPI() + + @app.get("/foobar") + async def _(): + headers = MultiMapping( + ("custom-test-header-1", "test-header-value-1"), + ("custom-test-header-2", "test-header-value-2"), + ("my-custom-regex-header-1", "my-custom-regex-value-1"), + ("my-custom-regex-header-1", "my-custom-regex-value-2"), + ("My-Custom-Regex-Header-2", "my-custom-regex-value-3"), + ("My-Custom-Regex-Header-2", "my-custom-regex-value-4"), + ("My-Secret-Header", "My Secret Value"), + ) + content = {"message": "hello world"} + return JSONResponse(content=content, headers=headers) + + return app + + def test_http_custom_request_headers_in_span_attributes(self): + expected = { + "http.request.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.request.header.custom_test_header_2": ( + "test-header-value-2", + ), + "http.request.header.regex_test_header_1": ("Regex Test Value 1",), + "http.request.header.regex_test_header_2": ( + "RegexTestValue2,RegexTestValue3", + ), + "http.request.header.my_secret_header": ("[REDACTED]",), + } + resp = self.client.get( + "/foobar", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + "Regex-Test-Header-1": "Regex Test Value 1", + "regex-test-header-2": "RegexTestValue2,RegexTestValue3", + "My-Secret-Header": "My Secret Value", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + self.assertSpanHasAttributes(server_span, expected) + + def test_http_custom_request_headers_not_in_span_attributes(self): + not_expected = { + "http.request.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + resp = self.client.get( + "/foobar", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + "Regex-Test-Header-1": "Regex Test Value 1", + "regex-test-header-2": "RegexTestValue2,RegexTestValue3", + "My-Secret-Header": "My Secret Value", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + def test_http_custom_response_headers_in_span_attributes(self): + expected = { + "http.response.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.response.header.custom_test_header_2": ( + "test-header-value-2", + ), + "http.response.header.my_custom_regex_header_1": ( + "my-custom-regex-value-1", + "my-custom-regex-value-2", + ), + "http.response.header.my_custom_regex_header_2": ( + "my-custom-regex-value-3", + "my-custom-regex-value-4", + ), + "http.response.header.my_secret_header": ("[REDACTED]",), + } + resp = self.client.get("/foobar") + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + self.assertSpanHasAttributes(server_span, expected) + + def test_http_custom_response_headers_not_in_span_attributes(self): + not_expected = { + "http.response.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + resp = self.client.get("/foobar") + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + +@patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*", + }, +) +class TestWebSocketAppWithCustomHeaders(TestBase): + def setUp(self): + super().setUp() + self.app = self._create_app() + otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) + self.client = TestClient(self.app) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) + + @staticmethod + def _create_app(): + app = fastapi.FastAPI() + + @app.websocket("/foobar_web") + async def _(websocket: fastapi.WebSocket): + message = await websocket.receive() + if message.get("type") == "websocket.connect": + await websocket.send( + { + "type": "websocket.accept", + "headers": [ + (b"custom-test-header-1", b"test-header-value-1"), + (b"custom-test-header-2", b"test-header-value-2"), + (b"Regex-Test-Header-1", b"Regex Test Value 1"), + ( + b"regex-test-header-2", + b"RegexTestValue2,RegexTestValue3", + ), + (b"My-Secret-Header", b"My Secret Value"), + ], + } + ) + await websocket.send_json({"message": "hello world"}) + await websocket.close() + if message.get("type") == "websocket.disconnect": + pass + + return app + + def test_web_socket_custom_request_headers_in_span_attributes(self): + expected = { + "http.request.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.request.header.custom_test_header_2": ( + "test-header-value-2", + ), + } + + with self.client.websocket_connect( + "/foobar_web", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + }, + ) as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + self.assertSpanHasAttributes(server_span, expected) + + @patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", + }, + ) + def test_web_socket_custom_request_headers_not_in_span_attributes(self): + not_expected = { + "http.request.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + + with self.client.websocket_connect( + "/foobar_web", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + }, + ) as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + def test_web_socket_custom_response_headers_in_span_attributes(self): + expected = { + "http.response.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.response.header.custom_test_header_2": ( + "test-header-value-2", + ), + } + + with self.client.websocket_connect("/foobar_web") as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + self.assertSpanHasAttributes(server_span, expected) + + def test_web_socket_custom_response_headers_not_in_span_attributes(self): + not_expected = { + "http.response.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + + with self.client.websocket_connect("/foobar_web") as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + +@patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3", + }, +) +class TestNonRecordingSpanWithCustomHeaders(TestBase): + def setUp(self): + super().setUp() + self.app = fastapi.FastAPI() + + @self.app.get("/foobar") + async def _(): + return {"message": "hello world"} + + reset_trace_globals() + tracer_provider = trace.NoOpTracerProvider() + trace.set_tracer_provider(tracer_provider=tracer_provider) + + self._instrumentor = otel_fastapi.FastAPIInstrumentor() + self._instrumentor.instrument_app(self.app) + self.client = TestClient(self.app) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + self._instrumentor.uninstrument_app(self.app) + + def test_custom_header_not_present_in_non_recording_span(self): + resp = self.client.get( + "/foobar", + headers={ + "custom-test-header-1": "test-header-value-1", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 0) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_wrapped.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_wrapped.py new file mode 100644 index 0000000000..0b17173ac6 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_wrapped.py @@ -0,0 +1,64 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import fastapi +from starlette.testclient import TestClient + +import opentelemetry.instrumentation.fastapi as otel_fastapi +from opentelemetry import trace +from opentelemetry.test.test_base import TestBase + + +class TestWrappedApplication(TestBase): + def setUp(self): + super().setUp() + + self.app = fastapi.FastAPI() + + @self.app.get("/foobar") + async def _(): + return {"message": "hello world"} + + otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) + self.client = TestClient(self.app) + self.tracer = self.tracer_provider.get_tracer(__name__) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) + + def test_mark_span_internal_in_presence_of_span_from_other_framework(self): + with self.tracer.start_as_current_span( + "test", kind=trace.SpanKind.SERVER + ) as parent_span: + resp = self.client.get("/foobar") + self.assertEqual(200, resp.status_code) + + span_list = self.memory_exporter.get_finished_spans() + for span in span_list: + print(str(span.__class__) + ": " + str(span.__dict__)) + + # there should be 4 spans - single SERVER "test" and three INTERNAL "FastAPI" + self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind) + self.assertEqual(trace.SpanKind.INTERNAL, span_list[1].kind) + # main INTERNAL span - child of test + self.assertEqual(trace.SpanKind.INTERNAL, span_list[2].kind) + self.assertEqual( + parent_span.context.span_id, span_list[2].parent.span_id + ) + # SERVER "test" + self.assertEqual(trace.SpanKind.SERVER, span_list[3].kind) + self.assertEqual( + parent_span.context.span_id, span_list[3].context.span_id + ) diff --git a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py index 1e768982b5..eed1a75c44 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -18,7 +18,7 @@ from starlette import applications from starlette.responses import PlainTextResponse -from starlette.routing import Route +from starlette.routing import Mount, Route from starlette.testclient import TestClient from starlette.websockets import WebSocket @@ -103,6 +103,43 @@ def test_basic_starlette_call(self): "opentelemetry.instrumentation.starlette", ) + def test_sub_app_starlette_call(self): + """ + This test is to ensure that a span in case of a sub app targeted contains the correct server url + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 3) + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + self.assertIn("GET /sub", span.name) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # expect only one span to have the attributes + self.assertEqual(1, len(spans_with_http_attributes)) + + for span in spans_with_http_attributes: + self.assertEqual( + "/sub/home", span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "http://testserver/sub/home", + span.attributes[SpanAttributes.HTTP_URL], + ) + def test_starlette_route_attribute_added(self): """Ensure that starlette routes are used as the span name.""" self._client.get("/user/123") @@ -250,13 +287,20 @@ def home(_): def health(_): return PlainTextResponse("ok") + def sub_home(_): + return PlainTextResponse("sub hi") + + sub_app = applications.Starlette(routes=[Route("/home", sub_home)]) + app = applications.Starlette( routes=[ Route("/foobar", home), Route("/user/{username}", home), Route("/healthzz", health), - ] + Mount("/sub", app=sub_app), + ], ) + return app @@ -354,6 +398,72 @@ def test_uninstrument(self): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) + def test_sub_app_starlette_call(self): + """ + !!! Attention: we need to override this testcase for the auto-instrumented variant + The reason is, that with auto instrumentation, the sub app is instrumented as well + and therefore we would see the spans for the sub app as well + + This test is to ensure that a span in case of a sub app targeted contains the correct server url + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 6) + + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + # -> the outer app is not aware of the sub_apps internal routes + sub_in = "GET /sub" in span.name + # The sub app spans are named GET /home as from the sub app perspective the request targets /home + # -> the sub app is technically not aware of the /sub prefix + home_in = "GET /home" in span.name + + # We expect the spans to be either from the outer app or the sub app + self.assertTrue( + sub_in or home_in, + f"Span {span.name} does not have /sub or /home in its name", + ) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # We now expect spans with attributes from both the app and its sub app + self.assertEqual(2, len(spans_with_http_attributes)) + + # Due to a potential bug in starlettes handling of sub app mounts, we can + # check only the server kind spans for the correct attributes + # The internal one generated by the sub app is not yet producing the correct attributes + server_span = next( + ( + span + for span in spans_with_http_attributes + if span.kind == SpanKind.SERVER + ), + None, + ) + + self.assertIsNotNone(server_span) + # As soon as the bug is fixed for starlette, we can iterate over spans_with_http_attributes here + # to verify the correctness of the attributes for the internal span as well + self.assertEqual( + "/sub/home", server_span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "http://testserver/sub/home", + server_span.attributes[SpanAttributes.HTTP_URL], + ) + class TestAutoInstrumentationHooks(TestStarletteManualInstrumentationHooks): """ @@ -374,6 +484,72 @@ def tearDown(self): self._instrumentor.uninstrument() super().tearDown() + def test_sub_app_starlette_call(self): + """ + !!! Attention: we need to override this testcase for the auto-instrumented variant + The reason is, that with auto instrumentation, the sub app is instrumented as well + and therefore we would see the spans for the sub app as well + + This test is to ensure that a span in case of a sub app targeted contains the correct server url + """ + + self._client.get("/sub/home") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 6) + + for span in spans: + # As we are only looking to the "outer" app, we would see only the "GET /sub" spans + # -> the outer app is not aware of the sub_apps internal routes + sub_in = "GET /sub" in span.name + # The sub app spans are named GET /home as from the sub app perspective the request targets /home + # -> the sub app is technically not aware of the /sub prefix + home_in = "GET /home" in span.name + + # We expect the spans to be either from the outer app or the sub app + self.assertTrue( + sub_in or home_in, + f"Span {span.name} does not have /sub or /home in its name", + ) + + # We now want to specifically test all spans including the + # - HTTP_TARGET + # - HTTP_URL + # attributes to be populated with the expected values + spans_with_http_attributes = [ + span + for span in spans + if ( + SpanAttributes.HTTP_URL in span.attributes + or SpanAttributes.HTTP_TARGET in span.attributes + ) + ] + + # We now expect spans with attributes from both the app and its sub app + self.assertEqual(2, len(spans_with_http_attributes)) + + # Due to a potential bug in starlettes handling of sub app mounts, we can + # check only the server kind spans for the correct attributes + # The internal one generated by the sub app is not yet producing the correct attributes + server_span = next( + ( + span + for span in spans_with_http_attributes + if span.kind == SpanKind.SERVER + ), + None, + ) + + self.assertIsNotNone(server_span) + # As soon as the bug is fixed for starlette, we can iterate over spans_with_http_attributes here + # to verify the correctness of the attributes for the internal span as well + self.assertEqual( + "/sub/home", server_span.attributes[SpanAttributes.HTTP_TARGET] + ) + self.assertEqual( + "http://testserver/sub/home", + server_span.attributes[SpanAttributes.HTTP_URL], + ) + class TestAutoInstrumentationLogic(unittest.TestCase): def test_instrumentation(self): From 8821a9520227d02b5287d9bf081ab74f580b9de3 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 3 Jul 2024 19:51:42 +0200 Subject: [PATCH 073/335] Test and lint opentelemetry-resource-detector-azure (#2651) --- .github/workflows/instrumentations_1.yml | 1 + .github/workflows/lint.yml | 1 + .../pyproject.toml | 1 + .../resource/detector/azure/app_service.py | 13 +++++-------- .../resource/detector/azure/functions.py | 9 ++++----- .../tests/test_app_service.py | 2 +- tox.ini | 18 ++++++++++++++++++ 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 7783105cd1..8f893fb260 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -35,6 +35,7 @@ jobs: - "sdk-extension-aws" - "propagator-aws-xray" - "propagator-ot-trace" + - "resource-detector-azure" - "resource-detector-container" os: [ubuntu-20.04] exclude: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index debecc6ff8..25e51779a1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -68,6 +68,7 @@ jobs: - "processor-baggage" - "propagator-aws-xray" - "propagator-ot-trace" + - "resource-detector-azure" - "resource-detector-container" - "sdk-extension-aws" os: [ubuntu-20.04] diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index f86f1f097b..fec99ef157 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-sdk ~= 1.21", + "opentelemetry-instrumentation == 0.47b0.dev", ] [project.entry-points.opentelemetry_resource_detector] diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py index 41371b8eec..7ca84a963d 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py @@ -12,23 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Optional from os import environ +from opentelemetry.resource.detector.azure._utils import ( + _get_azure_resource_uri, + _is_on_functions, +) from opentelemetry.sdk.resources import Resource, ResourceDetector from opentelemetry.semconv.resource import ( CloudPlatformValues, CloudProviderValues, ResourceAttributes, ) -from opentelemetry.resource.detector.azure._utils import _get_azure_resource_uri - -from ._constants import ( - _APP_SERVICE_ATTRIBUTE_ENV_VARS, - _WEBSITE_SITE_NAME, -) -from opentelemetry.resource.detector.azure._utils import _is_on_functions +from ._constants import _APP_SERVICE_ATTRIBUTE_ENV_VARS, _WEBSITE_SITE_NAME class AzureAppServiceResourceDetector(ResourceDetector): diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py index 0bf9a10f86..868c3cdd2b 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/functions.py @@ -14,6 +14,10 @@ from os import environ, getpid +from opentelemetry.resource.detector.azure._utils import ( + _get_azure_resource_uri, + _is_on_functions, +) from opentelemetry.sdk.resources import Resource, ResourceDetector from opentelemetry.semconv.resource import ( CloudPlatformValues, @@ -26,10 +30,6 @@ _REGION_NAME, _WEBSITE_SITE_NAME, ) -from opentelemetry.resource.detector.azure._utils import ( - _get_azure_resource_uri, - _is_on_functions, -) class AzureFunctionsResourceDetector(ResourceDetector): @@ -65,4 +65,3 @@ def detect(self) -> Resource: attributes[key] = value return Resource(attributes) - diff --git a/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py b/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py index 6c3d395994..4554440a38 100644 --- a/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py +++ b/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py @@ -68,7 +68,7 @@ def test_on_app_service(self): self.assertEqual( attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME ) - + @patch.dict( "os.environ", { diff --git a/tox.ini b/tox.ini index e18bdf6a6f..92a1cebd8b 100644 --- a/tox.ini +++ b/tox.ini @@ -11,6 +11,11 @@ envlist = pypy3-test-resource-detector-container lint-resource-detector-container + ; opentelemetry-resource-detector-azure + py3{8,9,10,11,12}-test-resource-detector-azure + pypy3-test-resource-detector-azure + lint-resource-detector-azure + ; opentelemetry-sdk-extension-aws py3{8,9,10,11,12}-test-sdk-extension-aws pypy3-test-sdk-extension-aws @@ -744,6 +749,12 @@ commands_pre = resource-detector-container: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils resource-detector-container: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-container/test-requirements.txt + resource-detector-azure: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + resource-detector-azure: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + resource-detector-azure: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + resource-detector-azure: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + resource-detector-azure: pip install -e {toxinidir}/resource/opentelemetry-resource-detector-azure -e {toxinidir}/opentelemetry-instrumentation + propagator-ot-trace: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api propagator-ot-trace: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions propagator-ot-trace: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -1139,6 +1150,13 @@ commands = lint-resource-detector-container: pylint {toxinidir}/resource/opentelemetry-resource-detector-container/src/opentelemetry lint-resource-detector-container: pylint {toxinidir}/resource/opentelemetry-resource-detector-container/tests + test-resource-detector-azure: pytest {toxinidir}/resource/opentelemetry-resource-detector-azure/tests {posargs} + lint-resource-detector-azure: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/resource/opentelemetry-resource-detector-azure + lint-resource-detector-azure: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/resource/opentelemetry-resource-detector-azure + lint-resource-detector-azure: flake8 --config {toxinidir}/.flake8 {toxinidir}/resource/opentelemetry-resource-detector-azure + lint-resource-detector-azure: pylint {toxinidir}/resource/opentelemetry-resource-detector-azure/src/opentelemetry + lint-resource-detector-azure: pylint {toxinidir}/resource/opentelemetry-resource-detector-azure/tests + test-processor-baggage: pytest {toxinidir}/processor/opentelemetry-processor-baggage/tests {posargs} lint-processor-baggage: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/processor/opentelemetry-processor-baggage lint-processor-baggage: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/processor/opentelemetry-processor-baggage From a3e457ca8cc70839d3d955268c271bc7d3356611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:00:27 -0300 Subject: [PATCH 074/335] add opentelemetry-util-http to CI (#2655) --- .github/workflows/instrumentations_1.yml | 1 + .github/workflows/lint.yml | 1 + tox.ini | 18 ++++++++++++------ .../tests/test_remove_credentials.py | 8 ++++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 8f893fb260..bd6f1aa2bf 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -37,6 +37,7 @@ jobs: - "propagator-ot-trace" - "resource-detector-azure" - "resource-detector-container" + - "util-http" os: [ubuntu-20.04] exclude: - python-version: pypy3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 25e51779a1..c156f7d942 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -71,6 +71,7 @@ jobs: - "resource-detector-azure" - "resource-detector-container" - "sdk-extension-aws" + - "util-http" os: [ubuntu-20.04] runs-on: ubuntu-20.04 steps: diff --git a/tox.ini b/tox.ini index 92a1cebd8b..b4d5203b9f 100644 --- a/tox.ini +++ b/tox.ini @@ -308,6 +308,7 @@ envlist = ; opentelemetry-util-http py3{8,9,10,11,12}-test-util-http pypy3-test-util-http + lint-util-http ; opentelemetry-propagator-aws-xray py3{8,9,10,11,12}-test-propagator-aws-xray @@ -772,12 +773,12 @@ commands_pre = processor-baggage: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk processor-baggage: pip install -r {toxinidir}/processor/opentelemetry-processor-baggage/test-requirements.txt - http: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - http: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - http: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - http: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - http: pip install -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt - http: pip install {toxinidir}/util/opentelemetry-util-http + util-http: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + util-http: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + util-http: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + util-http: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + util-http: pip install -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt + util-http: pip install {toxinidir}/util/opentelemetry-util-http ; In order to get a health coverage report, ; we have to install packages in editable mode. @@ -1135,6 +1136,11 @@ commands = lint-instrumentation-asyncio: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/tests test-util-http: pytest {toxinidir}/util/opentelemetry-util-http/tests {posargs} + lint-util-http: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/util/opentelemetry-util-http + lint-util-http: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/util/opentelemetry-util-http + lint-util-http: flake8 --config {toxinidir}/.flake8 {toxinidir}/util/opentelemetry-util-http + lint-util-http: pylint {toxinidir}/util/opentelemetry-util-http/src/opentelemetry + lint-util-http: pylint {toxinidir}/util/opentelemetry-util-http/tests test-sdk-extension-aws: pytest {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/tests {posargs} lint-sdk-extension-aws: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws diff --git a/util/opentelemetry-util-http/tests/test_remove_credentials.py b/util/opentelemetry-util-http/tests/test_remove_credentials.py index b6243145f5..2e50f1495f 100644 --- a/util/opentelemetry-util-http/tests/test_remove_credentials.py +++ b/util/opentelemetry-util-http/tests/test_remove_credentials.py @@ -19,9 +19,13 @@ def test_remove_credentials(self): def test_remove_credentials_ipv4_literal(self): url = "http://someuser:somepass@127.0.0.1:8080/test/path?query=value" cleaned_url = remove_url_credentials(url) - self.assertEqual(cleaned_url, "http://127.0.0.1:8080/test/path?query=value") + self.assertEqual( + cleaned_url, "http://127.0.0.1:8080/test/path?query=value" + ) def test_remove_credentials_ipv6_literal(self): url = "http://someuser:somepass@[::1]:8080/test/path?query=value" cleaned_url = remove_url_credentials(url) - self.assertEqual(cleaned_url, "http://[::1]:8080/test/path?query=value") + self.assertEqual( + cleaned_url, "http://[::1]:8080/test/path?query=value" + ) From c9bad6269cc63f7d7229b9d078cb10214a555ab7 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 3 Jul 2024 11:19:34 -0700 Subject: [PATCH 075/335] HTTP transition for asgi (#2610) --- CHANGELOG.md | 34 +- instrumentation/README.md | 2 +- .../instrumentation/asgi/__init__.py | 333 +++++-- .../instrumentation/asgi/package.py | 4 + .../tests/test_asgi_middleware.py | 827 +++++++++++++++++- .../tests/test_falcon.py | 2 - .../tests/test_programmatic.py | 4 - .../tests/test_automatic.py | 2 - .../instrumentation/wsgi/__init__.py | 2 +- .../opentelemetry/instrumentation/_semconv.py | 46 +- 10 files changed, 1111 insertions(+), 145 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fd9235c09..8e12ff8586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,19 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -- `opentelemetry-instrumentation-django` Handle exceptions from request/response hooks - ([#2153](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2153)) -- `opentelemetry-instrumentation-asyncio` instrumented `asyncio.wait_for` properly raises `asyncio.TimeoutError` as expected - ([#2637](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2637)) -- `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. - ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) -- `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. - ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) -- `opentelemetry-instrumentation-asgi` Fix generation of `http.target` and `http.url` attributes for ASGI apps - using sub apps - ([#2477](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2477)) - - ### Added - `opentelemetry-instrumentation-pyramid` Record exceptions raised when serving a request @@ -30,11 +17,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2616](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2616)) - `opentelemetry-instrumentation-confluent-kafka` Add support for produce purge ([#2638](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2638)) +- `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. + ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) ### Breaking changes - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette` Use `tracer` and `meter` of originating components instead of one from `asgi` middleware ([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580)) +- Populate `{method}` as `HTTP` on `_OTHER` methods from scope + ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) + +### Added + +- `opentelemetry-instrumentation-asgi` Implement new semantic convention opt-in with stable http semantic conventions + ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) ### Fixed @@ -50,6 +46,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2644](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2644)) - `opentelemetry-instrumentation-confluent-kafka` Confluent Kafka: Ensure consume span is ended when consumer is closed ([#2640](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2640)) +- `opentelemetry-instrumentation-asgi` Fix generation of `http.target` and `http.url` attributes for ASGI apps + using sub apps + ([#2477](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2477)) +- `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. + ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) +- `opentelemetry-instrumentation-asyncio` instrumented `asyncio.wait_for` properly raises `asyncio.TimeoutError` as expected + ([#2637](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2637)) +- `opentelemetry-instrumentation-django` Handle exceptions from request/response hooks + ([#2153](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2153)) +- `opentelemetry-instrumentation-asgi` Removed `NET_HOST_NAME` AND `NET_HOST_PORT` from active requests count attribute + ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) + ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/README.md b/instrumentation/README.md index 682334db1a..26c7d24daf 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -5,7 +5,7 @@ | [opentelemetry-instrumentation-aiohttp-client](./opentelemetry-instrumentation-aiohttp-client) | aiohttp ~= 3.0 | No | experimental | [opentelemetry-instrumentation-aiohttp-server](./opentelemetry-instrumentation-aiohttp-server) | aiohttp ~= 3.0 | No | experimental | [opentelemetry-instrumentation-aiopg](./opentelemetry-instrumentation-aiopg) | aiopg >= 0.13.0, < 2.0.0 | No | experimental -| [opentelemetry-instrumentation-asgi](./opentelemetry-instrumentation-asgi) | asgiref ~= 3.0 | No | experimental +| [opentelemetry-instrumentation-asgi](./opentelemetry-instrumentation-asgi) | asgiref ~= 3.0 | Yes | migration | [opentelemetry-instrumentation-asyncio](./opentelemetry-instrumentation-asyncio) | asyncio | No | experimental | [opentelemetry-instrumentation-asyncpg](./opentelemetry-instrumentation-asyncpg) | asyncpg >= 0.12.0 | No | experimental | [opentelemetry-instrumentation-aws-lambda](./opentelemetry-instrumentation-aws-lambda) | aws_lambda | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index b3cd9025c7..f006f9b0c9 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -201,6 +201,31 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from asgiref.compatibility import guarantee_single_callable from opentelemetry import context, trace +from opentelemetry.instrumentation._semconv import ( + _filter_semconv_active_request_count_attr, + _filter_semconv_duration_attrs, + _get_schema_url, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _report_old, + _server_active_requests_count_attrs_new, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new, + _server_duration_attrs_old, + _set_http_flavor_version, + _set_http_host, + _set_http_method, + _set_http_net_host_port, + _set_http_peer_ip, + _set_http_peer_port_server, + _set_http_scheme, + _set_http_target, + _set_http_url, + _set_http_user_agent, + _set_status, +) from opentelemetry.instrumentation.asgi.types import ( ClientRequestHook, ClientResponseHook, @@ -210,27 +235,31 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, ) -from opentelemetry.instrumentation.utils import ( - _start_internal_or_server_span, - http_status_to_status_code, -) +from opentelemetry.instrumentation.utils import _start_internal_or_server_span from opentelemetry.metrics import get_meter from opentelemetry.propagators.textmap import Getter, Setter +from opentelemetry.semconv._incubating.metrics.http_metrics import ( + create_http_server_active_requests, + create_http_server_request_body_size, + create_http_server_response_body_size, +) from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import set_span_in_context -from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import ( OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, SanitizeValue, - _parse_active_request_count_attrs, - _parse_duration_attrs, + _parse_url_query, get_custom_headers, normalise_request_header_name, normalise_response_header_name, remove_url_credentials, + sanitize_method, ) @@ -295,7 +324,10 @@ def set( asgi_setter = ASGISetter() -def collect_request_attributes(scope): +# pylint: disable=too-many-branches +def collect_request_attributes( + scope, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): """Collects HTTP request attributes from the ASGI scope and returns a dictionary to be used as span creation attributes.""" server_host, port, http_url = get_host_port_url_tuple(scope) @@ -304,31 +336,52 @@ def collect_request_attributes(scope): if isinstance(query_string, bytes): query_string = query_string.decode("utf8") http_url += "?" + urllib.parse.unquote(query_string) + result = {} + + scheme = scope.get("scheme") + if scheme: + _set_http_scheme(result, scheme, sem_conv_opt_in_mode) + if server_host: + _set_http_host(result, server_host, sem_conv_opt_in_mode) + if port: + _set_http_net_host_port(result, port, sem_conv_opt_in_mode) + flavor = scope.get("http_version") + if flavor: + _set_http_flavor_version(result, flavor, sem_conv_opt_in_mode) + path = scope.get("path") + if path: + _set_http_target( + result, path, path, query_string, sem_conv_opt_in_mode + ) + if http_url: + _set_http_url( + result, remove_url_credentials(http_url), sem_conv_opt_in_mode + ) - result = { - SpanAttributes.HTTP_SCHEME: scope.get("scheme"), - SpanAttributes.HTTP_HOST: server_host, - SpanAttributes.NET_HOST_PORT: port, - SpanAttributes.HTTP_FLAVOR: scope.get("http_version"), - SpanAttributes.HTTP_TARGET: scope.get("path"), - SpanAttributes.HTTP_URL: remove_url_credentials(http_url), - } - http_method = scope.get("method") + http_method = scope.get("method", "") if http_method: - result[SpanAttributes.HTTP_METHOD] = http_method + _set_http_method( + result, + http_method, + sanitize_method(http_method), + sem_conv_opt_in_mode, + ) http_host_value_list = asgi_getter.get(scope, "host") if http_host_value_list: - result[SpanAttributes.HTTP_SERVER_NAME] = ",".join( - http_host_value_list - ) + if _report_old(sem_conv_opt_in_mode): + result[SpanAttributes.HTTP_SERVER_NAME] = ",".join( + http_host_value_list + ) http_user_agent = asgi_getter.get(scope, "user-agent") if http_user_agent: - result[SpanAttributes.HTTP_USER_AGENT] = http_user_agent[0] + _set_http_user_agent(result, http_user_agent[0], sem_conv_opt_in_mode) if "client" in scope and scope["client"] is not None: - result[SpanAttributes.NET_PEER_IP] = scope.get("client")[0] - result[SpanAttributes.NET_PEER_PORT] = scope.get("client")[1] + _set_http_peer_ip(result, scope.get("client")[0], sem_conv_opt_in_mode) + _set_http_peer_port_server( + result, scope.get("client")[1], sem_conv_opt_in_mode + ) # remove None values result = {k: v for k, v in result.items() if v is not None} @@ -378,24 +431,30 @@ def get_host_port_url_tuple(scope): return server_host, port, http_url -def set_status_code(span, status_code): +def set_status_code( + span, + status_code, + metric_attributes=None, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, +): """Adds HTTP response attributes to span using the status_code argument.""" if not span.is_recording(): return + status_code_str = str(status_code) + try: status_code = int(status_code) except ValueError: - span.set_status( - Status( - StatusCode.ERROR, - "Non-integer HTTP status: " + repr(status_code), - ) - ) - else: - span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) - span.set_status( - Status(http_status_to_status_code(status_code, server_span=True)) - ) + status_code = -1 + if metric_attributes is None: + metric_attributes = {} + _set_status( + span, + metric_attributes, + status_code, + status_code_str, + sem_conv_opt_in_mode, + ) def get_default_span_details(scope: dict) -> Tuple[str, dict]: @@ -410,7 +469,9 @@ def get_default_span_details(scope: dict) -> Tuple[str, dict]: a tuple of the span name, and any attributes to attach to the span. """ path = scope.get("path", "").strip() - method = scope.get("method", "").strip() + method = sanitize_method(scope.get("method", "").strip()) + if method == "_OTHER": + method = "HTTP" if method and path: # http return f"{method} {path}", {} if path: # websocket @@ -484,13 +545,18 @@ def __init__( http_capture_headers_server_response: list[str] | None = None, http_capture_headers_sanitize_fields: list[str] | None = None, ): + # initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) self.app = guarantee_single_callable(app) self.tracer = ( trace.get_tracer( __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) if tracer is None else tracer @@ -500,30 +566,51 @@ def __init__( __name__, __version__, meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) if meter is None else meter ) - self.duration_histogram = self.meter.create_histogram( - name=MetricInstruments.HTTP_SERVER_DURATION, - unit="ms", - description="Duration of HTTP client requests.", - ) - self.server_response_size_histogram = self.meter.create_histogram( - name=MetricInstruments.HTTP_SERVER_RESPONSE_SIZE, - unit="By", - description="measures the size of HTTP response messages (compressed).", - ) - self.server_request_size_histogram = self.meter.create_histogram( - name=MetricInstruments.HTTP_SERVER_REQUEST_SIZE, - unit="By", - description="Measures the size of HTTP request messages (compressed).", - ) - self.active_requests_counter = self.meter.create_up_down_counter( - name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, - unit="requests", - description="measures the number of concurrent HTTP requests that are currently in-flight", + self.duration_histogram_old = None + if _report_old(sem_conv_opt_in_mode): + self.duration_histogram_old = self.meter.create_histogram( + name=MetricInstruments.HTTP_SERVER_DURATION, + unit="ms", + description="Duration of HTTP server requests.", + ) + self.duration_histogram_new = None + if _report_new(sem_conv_opt_in_mode): + self.duration_histogram_new = self.meter.create_histogram( + name=HTTP_SERVER_REQUEST_DURATION, + description="Duration of HTTP server requests.", + unit="s", + ) + self.server_response_size_histogram = None + if _report_old(sem_conv_opt_in_mode): + self.server_response_size_histogram = self.meter.create_histogram( + name=MetricInstruments.HTTP_SERVER_RESPONSE_SIZE, + unit="By", + description="measures the size of HTTP response messages (compressed).", + ) + self.server_response_body_size_histogram = None + if _report_new(sem_conv_opt_in_mode): + self.server_response_body_size_histogram = ( + create_http_server_response_body_size(self.meter) + ) + self.server_request_size_histogram = None + if _report_old(sem_conv_opt_in_mode): + self.server_request_size_histogram = self.meter.create_histogram( + name=MetricInstruments.HTTP_SERVER_REQUEST_SIZE, + unit="By", + description="Measures the size of HTTP request messages (compressed).", + ) + self.server_request_body_size_histogram = None + if _report_new(sem_conv_opt_in_mode): + self.server_request_body_size_histogram = ( + create_http_server_request_body_size(self.meter) + ) + self.active_requests_counter = create_http_server_active_requests( + self.meter ) self.excluded_urls = excluded_urls self.default_span_details = ( @@ -533,6 +620,7 @@ def __init__( self.client_request_hook = client_request_hook self.client_response_hook = client_response_hook self.content_length_header = None + self._sem_conv_opt_in_mode = sem_conv_opt_in_mode # Environment variables as constructor parameters self.http_capture_headers_server_request = ( @@ -563,6 +651,7 @@ def __init__( or [] ) + # pylint: disable=too-many-statements async def __call__( self, scope: dict[str, Any], @@ -586,7 +675,9 @@ async def __call__( span_name, additional_attributes = self.default_span_details(scope) - attributes = collect_request_attributes(scope) + attributes = collect_request_attributes( + scope, self._sem_conv_opt_in_mode + ) attributes.update(additional_attributes) span, token = _start_internal_or_server_span( tracer=self.tracer, @@ -597,9 +688,9 @@ async def __call__( attributes=attributes, ) active_requests_count_attrs = _parse_active_request_count_attrs( - attributes + attributes, + self._sem_conv_opt_in_mode, ) - duration_attrs = _parse_duration_attrs(attributes) if scope["type"] == "http": self.active_requests_counter.add(1, active_requests_count_attrs) @@ -635,7 +726,7 @@ async def __call__( span_name, scope, send, - duration_attrs, + attributes, ) await self.app(scope, otel_receive, otel_send) @@ -643,16 +734,44 @@ async def __call__( if scope["type"] == "http": target = _collect_target_attribute(scope) if target: - duration_attrs[SpanAttributes.HTTP_TARGET] = target - duration = max(round((default_timer() - start) * 1000), 0) - self.duration_histogram.record(duration, duration_attrs) + path, query = _parse_url_query(target) + _set_http_target( + attributes, + target, + path, + query, + self._sem_conv_opt_in_mode, + ) + duration_s = default_timer() - start + duration_attrs_old = _parse_duration_attrs( + attributes, _HTTPStabilityMode.DEFAULT + ) + if target: + duration_attrs_old[SpanAttributes.HTTP_TARGET] = target + duration_attrs_new = _parse_duration_attrs( + attributes, _HTTPStabilityMode.HTTP + ) + if self.duration_histogram_old: + self.duration_histogram_old.record( + max(round(duration_s * 1000), 0), duration_attrs_old + ) + if self.duration_histogram_new: + self.duration_histogram_new.record( + max(duration_s, 0), duration_attrs_new + ) self.active_requests_counter.add( -1, active_requests_count_attrs ) if self.content_length_header: - self.server_response_size_histogram.record( - self.content_length_header, duration_attrs - ) + if self.server_response_size_histogram: + self.server_response_size_histogram.record( + self.content_length_header, duration_attrs_old + ) + if self.server_response_body_size_histogram: + self.server_response_body_size_histogram.record( + self.content_length_header, duration_attrs_new + ) + request_size = asgi_getter.get(scope, "content-length") if request_size: try: @@ -660,9 +779,14 @@ async def __call__( except ValueError: pass else: - self.server_request_size_histogram.record( - request_size_amount, duration_attrs - ) + if self.server_request_size_histogram: + self.server_request_size_histogram.record( + request_size_amount, duration_attrs_old + ) + if self.server_request_body_size_histogram: + self.server_request_body_size_histogram.record( + request_size_amount, duration_attrs_new + ) if token: context.detach(token) if span.is_recording(): @@ -681,7 +805,12 @@ async def otel_receive(): self.client_request_hook(receive_span, scope, message) if receive_span.is_recording(): if message["type"] == "websocket.receive": - set_status_code(receive_span, 200) + set_status_code( + receive_span, + 200, + None, + self._sem_conv_opt_in_mode, + ) receive_span.set_attribute( "asgi.event.type", message["type"] ) @@ -690,7 +819,12 @@ async def otel_receive(): return otel_receive def _get_otel_send( - self, server_span, server_span_name, scope, send, duration_attrs + self, + server_span, + server_span_name, + scope, + send, + duration_attrs, ): expecting_trailers = False @@ -705,16 +839,33 @@ async def otel_send(message: dict[str, Any]): if send_span.is_recording(): if message["type"] == "http.response.start": status_code = message["status"] - duration_attrs[SpanAttributes.HTTP_STATUS_CODE] = ( - status_code + # We record metrics only once + set_status_code( + server_span, + status_code, + duration_attrs, + self._sem_conv_opt_in_mode, + ) + set_status_code( + send_span, + status_code, + None, + self._sem_conv_opt_in_mode, ) - set_status_code(server_span, status_code) - set_status_code(send_span, status_code) - expecting_trailers = message.get("trailers", False) elif message["type"] == "websocket.send": - set_status_code(server_span, 200) - set_status_code(send_span, 200) + set_status_code( + server_span, + 200, + duration_attrs, + self._sem_conv_opt_in_mode, + ) + set_status_code( + send_span, + 200, + None, + self._sem_conv_opt_in_mode, + ) send_span.set_attribute("asgi.event.type", message["type"]) if ( server_span.is_recording() @@ -767,3 +918,25 @@ async def otel_send(message: dict[str, Any]): server_span.end() return otel_send + + +def _parse_duration_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_duration_attrs( + req_attrs, + _server_duration_attrs_old, + _server_duration_attrs_new, + sem_conv_opt_in_mode, + ) + + +def _parse_active_request_count_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_active_request_count_attr( + req_attrs, + _server_active_requests_count_attrs_old, + _server_active_requests_count_attrs_new, + sem_conv_opt_in_mode, + ) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/package.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/package.py index c219ec5499..cd35b1f73a 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/package.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/package.py @@ -14,3 +14,7 @@ _instruments = ("asgiref ~= 3.0",) + +_supports_metrics = True + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index d2fe6bc52b..ff266cb5bf 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -23,6 +23,15 @@ import opentelemetry.instrumentation.asgi as otel_asgi from opentelemetry import trace as trace_api +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _server_active_requests_count_attrs_new, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new, + _server_duration_attrs_old, +) from opentelemetry.instrumentation.propagators import ( TraceResponsePropagator, get_global_response_propagator, @@ -33,6 +42,30 @@ HistogramDataPoint, NumberDataPoint, ) +from opentelemetry.semconv.attributes.client_attributes import ( + CLIENT_ADDRESS, + CLIENT_PORT, +) +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import ( + URL_FULL, + URL_PATH, + URL_QUERY, + URL_SCHEME, +) +from opentelemetry.semconv.attributes.user_agent_attributes import ( + USER_AGENT_ORIGINAL, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.asgitestutil import ( AsgiTestBase, @@ -40,24 +73,42 @@ ) from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind, format_span_id, format_trace_id -from opentelemetry.util.http import ( - _active_requests_count_attrs, - _duration_attrs, -) -_expected_metric_names = [ +_expected_metric_names_old = [ "http.server.active_requests", "http.server.duration", "http.server.response.size", "http.server.request.size", ] -_recommended_attrs = { - "http.server.active_requests": _active_requests_count_attrs, - "http.server.duration": _duration_attrs, - "http.server.response.size": _duration_attrs, - "http.server.request.size": _duration_attrs, +_expected_metric_names_new = [ + "http.server.active_requests", + "http.server.request.duration", + "http.server.response.body.size", + "http.server.request.body.size", +] +_expected_metric_names_both = _expected_metric_names_old +_expected_metric_names_both.extend(_expected_metric_names_new) + +_recommended_attrs_old = { + "http.server.active_requests": _server_active_requests_count_attrs_old, + "http.server.duration": _server_duration_attrs_old, + "http.server.response.size": _server_duration_attrs_old, + "http.server.request.size": _server_duration_attrs_old, +} + +_recommended_attrs_new = { + "http.server.active_requests": _server_active_requests_count_attrs_new, + "http.server.request.duration": _server_duration_attrs_new, + "http.server.response.body.size": _server_duration_attrs_new, + "http.server.request.body.size": _server_duration_attrs_new, } +_recommended_attrs_both = _recommended_attrs_old.copy() +_recommended_attrs_both.update(_recommended_attrs_new) +_recommended_attrs_both["http.server.active_requests"].extend( + _server_active_requests_count_attrs_old +) + _SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S = 0.01 @@ -229,7 +280,37 @@ async def error_asgi(scope, receive, send): # pylint: disable=too-many-public-methods class TestAsgiApplication(AsgiTestBase): - def validate_outputs(self, outputs, error=None, modifiers=None): + def setUp(self): + super().setUp() + + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + self.env_patch = mock.patch.dict( + "os.environ", + { + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, + }, + ) + + _OpenTelemetrySemanticConventionStability._initialized = False + + self.env_patch.start() + + # pylint: disable=too-many-locals + def validate_outputs( + self, + outputs, + error=None, + modifiers=None, + old_sem_conv=True, + new_sem_conv=False, + ): # Ensure modifiers is a list modifiers = modifiers or [] # Check for expected outputs @@ -264,7 +345,7 @@ def validate_outputs(self, outputs, error=None, modifiers=None): # Check spans span_list = self.memory_exporter.get_finished_spans() - expected = [ + expected_old = [ { "name": "GET / http receive", "kind": trace_api.SpanKind.INTERNAL, @@ -300,6 +381,96 @@ def validate_outputs(self, outputs, error=None, modifiers=None): }, }, ] + expected_new = [ + { + "name": "GET / http receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "http.request"}, + }, + { + "name": "GET / http send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": { + HTTP_RESPONSE_STATUS_CODE: 200, + "asgi.event.type": "http.response.start", + }, + }, + { + "name": "GET / http send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "http.response.body"}, + }, + { + "name": "GET /", + "kind": trace_api.SpanKind.SERVER, + "attributes": { + HTTP_REQUEST_METHOD: "GET", + URL_SCHEME: "http", + SERVER_PORT: 80, + SERVER_ADDRESS: "127.0.0.1", + NETWORK_PROTOCOL_VERSION: "1.0", + URL_PATH: "/", + URL_FULL: "http://127.0.0.1/", + CLIENT_ADDRESS: "127.0.0.1", + CLIENT_PORT: 32767, + HTTP_RESPONSE_STATUS_CODE: 200, + }, + }, + ] + expected_both = [ + { + "name": "GET / http receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "http.request"}, + }, + { + "name": "GET / http send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": { + SpanAttributes.HTTP_STATUS_CODE: 200, + HTTP_RESPONSE_STATUS_CODE: 200, + "asgi.event.type": "http.response.start", + }, + }, + { + "name": "GET / http send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "http.response.body"}, + }, + { + "name": "GET /", + "kind": trace_api.SpanKind.SERVER, + "attributes": { + HTTP_REQUEST_METHOD: "GET", + URL_SCHEME: "http", + SERVER_PORT: 80, + SERVER_ADDRESS: "127.0.0.1", + NETWORK_PROTOCOL_VERSION: "1.0", + URL_PATH: "/", + URL_FULL: "http://127.0.0.1/", + CLIENT_ADDRESS: "127.0.0.1", + CLIENT_PORT: 32767, + HTTP_RESPONSE_STATUS_CODE: 200, + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_SCHEME: "http", + SpanAttributes.NET_HOST_PORT: 80, + SpanAttributes.HTTP_HOST: "127.0.0.1", + SpanAttributes.HTTP_FLAVOR: "1.0", + SpanAttributes.HTTP_TARGET: "/", + SpanAttributes.HTTP_URL: "http://127.0.0.1/", + SpanAttributes.NET_PEER_IP: "127.0.0.1", + SpanAttributes.NET_PEER_PORT: 32767, + SpanAttributes.HTTP_STATUS_CODE: 200, + }, + }, + ] + expected = expected_old + if new_sem_conv: + if old_sem_conv: + expected = expected_both + else: + expected = expected_new + # Run our expected modifiers for modifier in modifiers: expected = modifier(expected) @@ -322,6 +493,22 @@ def test_basic_asgi_call(self): outputs = self.get_all_output() self.validate_outputs(outputs) + def test_basic_asgi_call_new_semconv(self): + """Test that spans are emitted as expected.""" + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs(outputs, old_sem_conv=False, new_sem_conv=True) + + def test_basic_asgi_call_both_semconv(self): + """Test that spans are emitted as expected.""" + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs(outputs, old_sem_conv=True, new_sem_conv=True) + def test_asgi_not_recording(self): mock_tracer = mock.Mock() mock_span = mock.Mock() @@ -496,6 +683,59 @@ def update_expected_server(expected): outputs = self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_server]) + def test_behavior_with_scope_server_as_none_new_semconv(self): + """Test that middleware is ok when server is none in scope.""" + + def update_expected_server(expected): + expected[3]["attributes"].update( + { + SERVER_ADDRESS: "0.0.0.0", + SERVER_PORT: 80, + URL_FULL: "http://0.0.0.0/", + } + ) + return expected + + self.scope["server"] = None + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs( + outputs, + modifiers=[update_expected_server], + old_sem_conv=False, + new_sem_conv=True, + ) + + def test_behavior_with_scope_server_as_none_both_semconv(self): + """Test that middleware is ok when server is none in scope.""" + + def update_expected_server(expected): + expected[3]["attributes"].update( + { + SpanAttributes.HTTP_HOST: "0.0.0.0", + SpanAttributes.NET_HOST_PORT: 80, + SpanAttributes.HTTP_URL: "http://0.0.0.0/", + SERVER_ADDRESS: "0.0.0.0", + SERVER_PORT: 80, + URL_FULL: "http://0.0.0.0/", + } + ) + return expected + + self.scope["server"] = None + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs( + outputs, + modifiers=[update_expected_server], + old_sem_conv=True, + new_sem_conv=True, + ) + def test_host_header(self): """Test that host header is converted to http.server_name.""" hostname = b"server_name_1" @@ -513,6 +753,28 @@ def update_expected_server(expected): outputs = self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_server]) + def test_host_header_both_semconv(self): + """Test that host header is converted to http.server_name.""" + hostname = b"server_name_1" + + def update_expected_server(expected): + expected[3]["attributes"].update( + {SpanAttributes.HTTP_SERVER_NAME: hostname.decode("utf8")} + ) + return expected + + self.scope["headers"].append([b"host", hostname]) + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs( + outputs, + modifiers=[update_expected_server], + old_sem_conv=True, + new_sem_conv=True, + ) + def test_user_agent(self): """Test that host header is converted to http.server_name.""" user_agent = b"test-agent" @@ -530,6 +792,53 @@ def update_expected_user_agent(expected): outputs = self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_user_agent]) + def test_user_agent_new_semconv(self): + """Test that host header is converted to http.server_name.""" + user_agent = b"test-agent" + + def update_expected_user_agent(expected): + expected[3]["attributes"].update( + {USER_AGENT_ORIGINAL: user_agent.decode("utf8")} + ) + return expected + + self.scope["headers"].append([b"user-agent", user_agent]) + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs( + outputs, + modifiers=[update_expected_user_agent], + old_sem_conv=False, + new_sem_conv=True, + ) + + def test_user_agent_both_semconv(self): + """Test that host header is converted to http.server_name.""" + user_agent = b"test-agent" + + def update_expected_user_agent(expected): + expected[3]["attributes"].update( + { + SpanAttributes.HTTP_USER_AGENT: user_agent.decode("utf8"), + USER_AGENT_ORIGINAL: user_agent.decode("utf8"), + } + ) + return expected + + self.scope["headers"].append([b"user-agent", user_agent]) + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + outputs = self.get_all_output() + self.validate_outputs( + outputs, + modifiers=[update_expected_user_agent], + old_sem_conv=True, + new_sem_conv=True, + ) + def test_traceresponse_header(self): """Test a traceresponse header is sent when a global propagator is set.""" @@ -565,6 +874,7 @@ def test_traceresponse_header(self): def test_websocket(self): self.scope = { + "method": "GET", "type": "websocket", "http_version": "1.1", "scheme": "ws", @@ -584,17 +894,17 @@ def test_websocket(self): self.assertEqual(len(span_list), 6) expected = [ { - "name": "/ websocket receive", + "name": "GET / websocket receive", "kind": trace_api.SpanKind.INTERNAL, "attributes": {"asgi.event.type": "websocket.connect"}, }, { - "name": "/ websocket send", + "name": "GET / websocket send", "kind": trace_api.SpanKind.INTERNAL, "attributes": {"asgi.event.type": "websocket.accept"}, }, { - "name": "/ websocket receive", + "name": "GET / websocket receive", "kind": trace_api.SpanKind.INTERNAL, "attributes": { "asgi.event.type": "websocket.receive", @@ -602,7 +912,7 @@ def test_websocket(self): }, }, { - "name": "/ websocket send", + "name": "GET / websocket send", "kind": trace_api.SpanKind.INTERNAL, "attributes": { "asgi.event.type": "websocket.send", @@ -610,12 +920,12 @@ def test_websocket(self): }, }, { - "name": "/ websocket receive", + "name": "GET / websocket receive", "kind": trace_api.SpanKind.INTERNAL, "attributes": {"asgi.event.type": "websocket.disconnect"}, }, { - "name": "/", + "name": "GET /", "kind": trace_api.SpanKind.SERVER, "attributes": { SpanAttributes.HTTP_SCHEME: self.scope["scheme"], @@ -627,6 +937,167 @@ def test_websocket(self): SpanAttributes.NET_PEER_IP: self.scope["client"][0], SpanAttributes.NET_PEER_PORT: self.scope["client"][1], SpanAttributes.HTTP_STATUS_CODE: 200, + SpanAttributes.HTTP_METHOD: self.scope["method"], + }, + }, + ] + for span, expected in zip(span_list, expected): + self.assertEqual(span.name, expected["name"]) + self.assertEqual(span.kind, expected["kind"]) + self.assertDictEqual(dict(span.attributes), expected["attributes"]) + + def test_websocket_new_semconv(self): + self.scope = { + "method": "GET", + "type": "websocket", + "http_version": "1.1", + "scheme": "ws", + "path": "/", + "query_string": b"", + "headers": [], + "client": ("127.0.0.1", 32767), + "server": ("127.0.0.1", 80), + } + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_input({"type": "websocket.connect"}) + self.send_input({"type": "websocket.receive", "text": "ping"}) + self.send_input({"type": "websocket.disconnect"}) + self.get_all_output() + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 6) + expected = [ + { + "name": "GET / websocket receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "websocket.connect"}, + }, + { + "name": "GET / websocket send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "websocket.accept"}, + }, + { + "name": "GET / websocket receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": { + "asgi.event.type": "websocket.receive", + HTTP_RESPONSE_STATUS_CODE: 200, + }, + }, + { + "name": "GET / websocket send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": { + "asgi.event.type": "websocket.send", + HTTP_RESPONSE_STATUS_CODE: 200, + }, + }, + { + "name": "GET / websocket receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "websocket.disconnect"}, + }, + { + "name": "GET /", + "kind": trace_api.SpanKind.SERVER, + "attributes": { + URL_SCHEME: self.scope["scheme"], + SERVER_PORT: self.scope["server"][1], + SERVER_ADDRESS: self.scope["server"][0], + NETWORK_PROTOCOL_VERSION: self.scope["http_version"], + URL_PATH: self.scope["path"], + URL_FULL: f'{self.scope["scheme"]}://{self.scope["server"][0]}{self.scope["path"]}', + CLIENT_ADDRESS: self.scope["client"][0], + CLIENT_PORT: self.scope["client"][1], + HTTP_RESPONSE_STATUS_CODE: 200, + HTTP_REQUEST_METHOD: self.scope["method"], + }, + }, + ] + for span, expected in zip(span_list, expected): + self.assertEqual(span.name, expected["name"]) + self.assertEqual(span.kind, expected["kind"]) + self.assertDictEqual(dict(span.attributes), expected["attributes"]) + + def test_websocket_both_semconv(self): + self.scope = { + "method": "GET", + "type": "websocket", + "http_version": "1.1", + "scheme": "ws", + "path": "/", + "query_string": b"", + "headers": [], + "client": ("127.0.0.1", 32767), + "server": ("127.0.0.1", 80), + } + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_input({"type": "websocket.connect"}) + self.send_input({"type": "websocket.receive", "text": "ping"}) + self.send_input({"type": "websocket.disconnect"}) + self.get_all_output() + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 6) + expected = [ + { + "name": "GET / websocket receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "websocket.connect"}, + }, + { + "name": "GET / websocket send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "websocket.accept"}, + }, + { + "name": "GET / websocket receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": { + "asgi.event.type": "websocket.receive", + HTTP_RESPONSE_STATUS_CODE: 200, + SpanAttributes.HTTP_STATUS_CODE: 200, + }, + }, + { + "name": "GET / websocket send", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": { + "asgi.event.type": "websocket.send", + HTTP_RESPONSE_STATUS_CODE: 200, + SpanAttributes.HTTP_STATUS_CODE: 200, + }, + }, + { + "name": "GET / websocket receive", + "kind": trace_api.SpanKind.INTERNAL, + "attributes": {"asgi.event.type": "websocket.disconnect"}, + }, + { + "name": "GET /", + "kind": trace_api.SpanKind.SERVER, + "attributes": { + SpanAttributes.HTTP_SCHEME: self.scope["scheme"], + SpanAttributes.NET_HOST_PORT: self.scope["server"][1], + SpanAttributes.HTTP_HOST: self.scope["server"][0], + SpanAttributes.HTTP_FLAVOR: self.scope["http_version"], + SpanAttributes.HTTP_TARGET: self.scope["path"], + SpanAttributes.HTTP_URL: f'{self.scope["scheme"]}://{self.scope["server"][0]}{self.scope["path"]}', + SpanAttributes.NET_PEER_IP: self.scope["client"][0], + SpanAttributes.NET_PEER_PORT: self.scope["client"][1], + SpanAttributes.HTTP_STATUS_CODE: 200, + SpanAttributes.HTTP_METHOD: self.scope["method"], + URL_SCHEME: self.scope["scheme"], + SERVER_PORT: self.scope["server"][1], + SERVER_ADDRESS: self.scope["server"][0], + NETWORK_PROTOCOL_VERSION: self.scope["http_version"], + URL_PATH: self.scope["path"], + URL_FULL: f'{self.scope["scheme"]}://{self.scope["server"][0]}{self.scope["path"]}', + CLIENT_ADDRESS: self.scope["client"][0], + CLIENT_PORT: self.scope["client"][1], + HTTP_RESPONSE_STATUS_CODE: 200, + HTTP_REQUEST_METHOD: self.scope["method"], }, }, ] @@ -737,7 +1208,7 @@ def test_asgi_metrics(self): "opentelemetry.instrumentation.asgi", ) for metric in scope_metric.metrics: - self.assertIn(metric.name, _expected_metric_names) + self.assertIn(metric.name, _expected_metric_names_old) data_points = list(metric.data.data_points) self.assertEqual(len(data_points), 1) for point in data_points: @@ -748,7 +1219,79 @@ def test_asgi_metrics(self): number_data_point_seen = True for attr in point.attributes: self.assertIn( - attr, _recommended_attrs[metric.name] + attr, _recommended_attrs_old[metric.name] + ) + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + + def test_asgi_metrics_new_semconv(self): + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + self.seed_app(app) + self.send_default_request() + self.seed_app(app) + self.send_default_request() + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histogram_data_point_seen = False + self.assertTrue(len(metrics_list.resource_metrics) != 0) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) != 0) + for scope_metric in resource_metric.scope_metrics: + self.assertTrue(len(scope_metric.metrics) != 0) + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.asgi", + ) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names_new) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs_new[metric.name] + ) + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + + def test_asgi_metrics_both_semconv(self): + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + self.seed_app(app) + self.send_default_request() + self.seed_app(app) + self.send_default_request() + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histogram_data_point_seen = False + self.assertTrue(len(metrics_list.resource_metrics) != 0) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) != 0) + for scope_metric in resource_metric.scope_metrics: + self.assertTrue(len(scope_metric.metrics) != 0) + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.asgi", + ) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names_both) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs_both[metric.name] ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) @@ -799,6 +1342,141 @@ def test_basic_metric_success(self): ) self.assertEqual(point.value, 0) + def test_basic_metric_success_new_semconv(self): + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + start = default_timer() + self.send_default_request() + duration_s = max(default_timer() - start, 0) + expected_duration_attributes = { + "http.request.method": "GET", + "url.scheme": "http", + "network.protocol.version": "1.0", + "http.response.status_code": 200, + } + expected_requests_count_attributes = { + "http.request.method": "GET", + "url.scheme": "http", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + # pylint: disable=too-many-nested-blocks + for resource_metric in metrics_list.resource_metrics: + for scope_metrics in resource_metric.scope_metrics: + for metric in scope_metrics.metrics: + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) + self.assertEqual(point.count, 1) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual( + duration_s, point.sum, places=2 + ) + elif ( + metric.name == "http.server.response.body.size" + ): + self.assertEqual(1024, point.sum) + elif ( + metric.name == "http.server.request.body.size" + ): + self.assertEqual(128, point.sum) + elif isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_metric_success_both_semconv(self): + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + start = default_timer() + self.send_default_request() + duration = max(round((default_timer() - start) * 1000), 0) + duration_s = max(default_timer() - start, 0) + expected_duration_attributes_old = { + "http.method": "GET", + "http.host": "127.0.0.1", + "http.scheme": "http", + "http.flavor": "1.0", + "net.host.port": 80, + "http.status_code": 200, + } + expected_requests_count_attributes = { + "http.method": "GET", + "http.host": "127.0.0.1", + "http.scheme": "http", + "http.flavor": "1.0", + "http.request.method": "GET", + "url.scheme": "http", + } + expected_duration_attributes_new = { + "http.request.method": "GET", + "url.scheme": "http", + "network.protocol.version": "1.0", + "http.response.status_code": 200, + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + # pylint: disable=too-many-nested-blocks + for resource_metric in metrics_list.resource_metrics: + for scope_metrics in resource_metric.scope_metrics: + for metric in scope_metrics.metrics: + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual( + duration_s, point.sum, places=2 + ) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif ( + metric.name == "http.server.response.body.size" + ): + self.assertEqual(1024, point.sum) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif ( + metric.name == "http.server.request.body.size" + ): + self.assertEqual(128, point.sum) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.duration": + self.assertAlmostEqual( + duration, point.sum, delta=5 + ) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif metric.name == "http.server.response.size": + self.assertEqual(1024, point.sum) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif metric.name == "http.server.request.size": + self.assertEqual(128, point.sum) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + def test_metric_target_attribute(self): expected_target = "/api/user/{id}" @@ -882,6 +1560,70 @@ def test_request_attributes(self): }, ) + def test_request_attributes_new_semconv(self): + self.scope["query_string"] = b"foo=bar" + headers = [] + headers.append((b"host", b"test")) + self.scope["headers"] = headers + + attrs = otel_asgi.collect_request_attributes( + self.scope, + _HTTPStabilityMode.HTTP, + ) + + self.assertDictEqual( + attrs, + { + HTTP_REQUEST_METHOD: "GET", + SERVER_ADDRESS: "127.0.0.1", + URL_PATH: "/", + URL_QUERY: "foo=bar", + URL_FULL: "http://127.0.0.1/?foo=bar", + SERVER_PORT: 80, + URL_SCHEME: "http", + NETWORK_PROTOCOL_VERSION: "1.0", + CLIENT_ADDRESS: "127.0.0.1", + CLIENT_PORT: 32767, + }, + ) + + def test_request_attributes_both_semconv(self): + self.scope["query_string"] = b"foo=bar" + headers = [] + headers.append((b"host", b"test")) + self.scope["headers"] = headers + + attrs = otel_asgi.collect_request_attributes( + self.scope, + _HTTPStabilityMode.HTTP_DUP, + ) + + self.assertDictEqual( + attrs, + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_HOST: "127.0.0.1", + SpanAttributes.HTTP_TARGET: "/", + SpanAttributes.HTTP_URL: "http://127.0.0.1/?foo=bar", + SpanAttributes.NET_HOST_PORT: 80, + SpanAttributes.HTTP_SCHEME: "http", + SpanAttributes.HTTP_SERVER_NAME: "test", + SpanAttributes.HTTP_FLAVOR: "1.0", + SpanAttributes.NET_PEER_IP: "127.0.0.1", + SpanAttributes.NET_PEER_PORT: 32767, + HTTP_REQUEST_METHOD: "GET", + SERVER_ADDRESS: "127.0.0.1", + URL_PATH: "/", + URL_QUERY: "foo=bar", + URL_FULL: "http://127.0.0.1/?foo=bar", + SERVER_PORT: 80, + URL_SCHEME: "http", + NETWORK_PROTOCOL_VERSION: "1.0", + CLIENT_ADDRESS: "127.0.0.1", + CLIENT_PORT: 32767, + }, + ) + def test_query_string(self): self.scope["query_string"] = b"foo=bar" attrs = otel_asgi.collect_request_attributes(self.scope) @@ -889,6 +1631,25 @@ def test_query_string(self): attrs[SpanAttributes.HTTP_URL], "http://127.0.0.1/?foo=bar" ) + def test_query_string_new_semconv(self): + self.scope["query_string"] = b"foo=bar" + attrs = otel_asgi.collect_request_attributes( + self.scope, + _HTTPStabilityMode.HTTP, + ) + self.assertEqual(attrs[URL_FULL], "http://127.0.0.1/?foo=bar") + + def test_query_string_both_semconv(self): + self.scope["query_string"] = b"foo=bar" + attrs = otel_asgi.collect_request_attributes( + self.scope, + _HTTPStabilityMode.HTTP_DUP, + ) + self.assertEqual(attrs[URL_FULL], "http://127.0.0.1/?foo=bar") + self.assertEqual( + attrs[SpanAttributes.HTTP_URL], "http://127.0.0.1/?foo=bar" + ) + def test_query_string_percent_bytes(self): self.scope["query_string"] = b"foo%3Dbar" attrs = otel_asgi.collect_request_attributes(self.scope) @@ -910,6 +1671,32 @@ def test_response_attributes(self): self.assertEqual(self.span.set_attribute.call_count, 1) self.span.set_attribute.assert_has_calls(expected, any_order=True) + def test_response_attributes_new_semconv(self): + otel_asgi.set_status_code( + self.span, + 404, + None, + _HTTPStabilityMode.HTTP, + ) + expected = (mock.call(HTTP_RESPONSE_STATUS_CODE, 404),) + self.assertEqual(self.span.set_attribute.call_count, 1) + self.assertEqual(self.span.set_attribute.call_count, 1) + self.span.set_attribute.assert_has_calls(expected, any_order=True) + + def test_response_attributes_both_semconv(self): + otel_asgi.set_status_code( + self.span, + 404, + None, + _HTTPStabilityMode.HTTP_DUP, + ) + expected = (mock.call(SpanAttributes.HTTP_STATUS_CODE, 404),) + expected2 = (mock.call(HTTP_RESPONSE_STATUS_CODE, 404),) + self.assertEqual(self.span.set_attribute.call_count, 2) + self.assertEqual(self.span.set_attribute.call_count, 2) + self.span.set_attribute.assert_has_calls(expected, any_order=True) + self.span.set_attribute.assert_has_calls(expected2, any_order=True) + def test_response_attributes_invalid_status_code(self): otel_asgi.set_status_code(self.span, "Invalid Status Code") self.assertEqual(self.span.set_status.call_count, 1) diff --git a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py index bf7f1d4f49..dbc2512ca0 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py @@ -345,8 +345,6 @@ def test_falcon_metric_values(self): "http.scheme": "http", "http.flavor": "1.1", "http.server_name": "falconframework.org", - "net.host.name": "falconframework.org", - "net.host.port": 80, } start = default_timer() self.client().simulate_get("/hello/756") diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 3f47eebcca..94437bbfd2 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -584,8 +584,6 @@ def test_basic_metric_success(self): "http.scheme": "http", "http.flavor": "1.1", "http.server_name": "localhost", - "net.host.name": "localhost", - "net.host.port": 80, } self._assert_basic_metric( expected_duration_attributes, @@ -627,8 +625,6 @@ def test_basic_metric_nonstandard_http_method_success(self): "http.scheme": "http", "http.flavor": "1.1", "http.server_name": "localhost", - "net.host.name": "localhost", - "net.host.port": 80, } self._assert_basic_metric( expected_duration_attributes, diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py index b1d854b371..b40cf3355a 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_automatic.py @@ -224,8 +224,6 @@ def test_basic_metric_success(self): "http.scheme": "http", "http.flavor": "1.1", "http.server_name": "localhost", - "net.host.name": "localhost", - "net.host.port": 80, } metrics_list = self.memory_metrics_reader.get_metrics_data() for metric in ( diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 6a1883fa7e..d75147d6aa 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -494,8 +494,8 @@ def add_response_attributes( _set_status( span, duration_attrs, - status_code_str, status_code, + status_code_str, sem_conv_opt_in_mode, ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index baa06ff99b..85b8e2e3ec 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -17,6 +17,10 @@ from enum import Enum from opentelemetry.instrumentation.utils import http_status_to_status_code +from opentelemetry.semconv.attributes.client_attributes import ( + CLIENT_ADDRESS, + CLIENT_PORT, +) from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.attributes.http_attributes import ( HTTP_REQUEST_METHOD, @@ -33,11 +37,18 @@ ) from opentelemetry.semconv.attributes.url_attributes import ( URL_FULL, + URL_PATH, + URL_QUERY, URL_SCHEME, ) +from opentelemetry.semconv.attributes.user_agent_attributes import ( + USER_AGENT_ORIGINAL, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode +# These lists represent attributes for metrics that are currently supported + _client_duration_attrs_old = [ SpanAttributes.HTTP_STATUS_CODE, SpanAttributes.HTTP_HOST, @@ -85,13 +96,12 @@ SpanAttributes.HTTP_SCHEME, SpanAttributes.HTTP_FLAVOR, SpanAttributes.HTTP_SERVER_NAME, - SpanAttributes.NET_HOST_NAME, - SpanAttributes.NET_HOST_PORT, ] _server_active_requests_count_attrs_new = [ HTTP_REQUEST_METHOD, URL_SCHEME, + # TODO: Support SERVER_ADDRESS AND SERVER_PORT ] OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" @@ -280,14 +290,14 @@ def _set_http_net_host(result, host, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.NET_HOST_NAME, host) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.SERVER_ADDRESS, host) + set_string_attribute(result, SERVER_ADDRESS, host) def _set_http_net_host_port(result, port, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_int_attribute(result, SpanAttributes.NET_HOST_PORT, port) if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, SpanAttributes.SERVER_PORT, port) + set_int_attribute(result, SERVER_PORT, port) def _set_http_target(result, target, path, query, sem_conv_opt_in_mode): @@ -295,23 +305,23 @@ def _set_http_target(result, target, path, query, sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_TARGET, target) if _report_new(sem_conv_opt_in_mode): if path: - set_string_attribute(result, SpanAttributes.URL_PATH, path) + set_string_attribute(result, URL_PATH, path) if query: - set_string_attribute(result, SpanAttributes.URL_QUERY, query) + set_string_attribute(result, URL_QUERY, query) def _set_http_peer_ip(result, ip, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.NET_PEER_IP, ip) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.CLIENT_ADDRESS, ip) + set_string_attribute(result, CLIENT_ADDRESS, ip) def _set_http_peer_port_server(result, port, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port) if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, SpanAttributes.CLIENT_PORT, port) + set_int_attribute(result, CLIENT_PORT, port) def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode): @@ -320,32 +330,28 @@ def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode): result, SpanAttributes.HTTP_USER_AGENT, user_agent ) if _report_new(sem_conv_opt_in_mode): - set_string_attribute( - result, SpanAttributes.USER_AGENT_ORIGINAL, user_agent - ) + set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent) def _set_http_net_peer_name_server(result, name, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.NET_PEER_NAME, name) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.CLIENT_ADDRESS, name) + set_string_attribute(result, CLIENT_ADDRESS, name) def _set_http_flavor_version(result, version, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version) if _report_new(sem_conv_opt_in_mode): - set_string_attribute( - result, SpanAttributes.NETWORK_PROTOCOL_VERSION, version - ) + set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) def _set_status( span, metrics_attributes, - status_code_str, status_code, + status_code_str, sem_conv_opt_in_mode, ): if status_code < 0: @@ -366,12 +372,8 @@ def _set_status( span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) metrics_attributes[SpanAttributes.HTTP_STATUS_CODE] = status_code if _report_new(sem_conv_opt_in_mode): - span.set_attribute( - SpanAttributes.HTTP_RESPONSE_STATUS_CODE, status_code - ) - metrics_attributes[SpanAttributes.HTTP_RESPONSE_STATUS_CODE] = ( - status_code - ) + span.set_attribute(HTTP_RESPONSE_STATUS_CODE, status_code) + metrics_attributes[HTTP_RESPONSE_STATUS_CODE] = status_code if status == StatusCode.ERROR: span.set_attribute(ERROR_TYPE, status_code_str) metrics_attributes[ERROR_TYPE] = status_code_str From 7da7f554ea3aaf3045cbb1933ae9234e4b44d39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:43:47 -0300 Subject: [PATCH 076/335] HTTP semantic convention stability migration for httpx (#2631) --- CHANGELOG.md | 2 + instrumentation/README.md | 2 +- .../instrumentation/httpx/__init__.py | 281 +++++++++++++----- .../instrumentation/httpx/package.py | 4 + .../tests/test_httpx_integration.py | 272 ++++++++++++++++- 5 files changed, 490 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e12ff8586..b5031bc905 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2616](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2616)) - `opentelemetry-instrumentation-confluent-kafka` Add support for produce purge ([#2638](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2638)) +- `opentelemetry-instrumentation-httpx` Implement new semantic convention opt-in migration with stable http semantic conventions + ([#2631](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2631)) - `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) diff --git a/instrumentation/README.md b/instrumentation/README.md index 26c7d24daf..eb21717843 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -22,7 +22,7 @@ | [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | experimental | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental -| [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | experimental +| [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration | [opentelemetry-instrumentation-jinja2](./opentelemetry-instrumentation-jinja2) | jinja2 >= 2.7, < 4.0 | No | experimental | [opentelemetry-instrumentation-kafka-python](./opentelemetry-instrumentation-kafka-python) | kafka-python >= 2.0 | No | experimental | [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 5404b2f025..d2ff0be292 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -196,6 +196,19 @@ async def async_response_hook(span, request, response): import httpx +from opentelemetry.instrumentation._semconv import ( + _get_schema_url, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _set_http_host, + _set_http_method, + _set_http_network_protocol_version, + _set_http_peer_port_client, + _set_http_status_code, + _set_http_url, +) from opentelemetry.instrumentation.httpx.package import _instruments from opentelemetry.instrumentation.httpx.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -204,11 +217,15 @@ async def async_response_hook(span, request, response): is_http_instrumentation_enabled, ) from opentelemetry.propagate import inject -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PEER_ADDRESS, + NETWORK_PEER_PORT, +) from opentelemetry.trace import SpanKind, TracerProvider, get_tracer from opentelemetry.trace.span import Span -from opentelemetry.trace.status import Status -from opentelemetry.util.http import remove_url_credentials +from opentelemetry.trace.status import StatusCode +from opentelemetry.util.http import remove_url_credentials, sanitize_method _logger = logging.getLogger(__name__) @@ -242,25 +259,11 @@ class ResponseInfo(typing.NamedTuple): def _get_default_span_name(method: str) -> str: - return method.strip() - - -def _apply_status_code(span: Span, status_code: int) -> None: - if not span.is_recording(): - return + method = sanitize_method(method.upper().strip()) + if method == "_OTHER": + method = "HTTP" - span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) - span.set_status(Status(http_status_to_status_code(status_code))) - - -def _prepare_attributes(method: bytes, url: URL) -> typing.Dict[str, str]: - _method = method.decode().upper() - _url = str(httpx.URL(url)) - span_attributes = { - SpanAttributes.HTTP_METHOD: _method, - SpanAttributes.HTTP_URL: _url, - } - return span_attributes + return method def _prepare_headers(headers: typing.Optional[Headers]) -> httpx.Headers: @@ -299,6 +302,84 @@ def _inject_propagation_headers(headers, args, kwargs): kwargs["headers"] = _headers.raw +def _extract_response( + response: typing.Union[ + httpx.Response, typing.Tuple[int, Headers, httpx.SyncByteStream, dict] + ] +) -> typing.Tuple[int, Headers, httpx.SyncByteStream, dict, str]: + if isinstance(response, httpx.Response): + status_code = response.status_code + headers = response.headers + stream = response.stream + extensions = response.extensions + http_version = response.http_version + else: + status_code, headers, stream, extensions = response + http_version = extensions.get("http_version", b"HTTP/1.1").decode( + "ascii", errors="ignore" + ) + + return (status_code, headers, stream, extensions, http_version) + + +def _apply_request_client_attributes_to_span( + span_attributes: dict, + url: typing.Union[str, URL, httpx.URL], + method_original: str, + span_name: str, + semconv: _HTTPStabilityMode, +): + url = httpx.URL(url) + # http semconv transition: http.method -> http.request.method + _set_http_method(span_attributes, method_original, span_name, semconv) + # http semconv transition: http.url -> url.full + _set_http_url(span_attributes, str(url), semconv) + + if _report_new(semconv): + if url.host: + # http semconv transition: http.host -> server.address + _set_http_host(span_attributes, url.host, semconv) + # http semconv transition: net.sock.peer.addr -> network.peer.address + span_attributes[NETWORK_PEER_ADDRESS] = url.host + if url.port: + # http semconv transition: net.sock.peer.port -> network.peer.port + _set_http_peer_port_client(span_attributes, url.port, semconv) + span_attributes[NETWORK_PEER_PORT] = url.port + + +def _apply_response_client_attributes_to_span( + span: Span, + status_code: int, + http_version: str, + semconv: _HTTPStabilityMode, +): + # http semconv transition: http.status_code -> http.response.status_code + # TODO: use _set_status when it's stable for http clients + span_attributes = {} + _set_http_status_code( + span_attributes, + status_code, + semconv, + ) + http_status_code = http_status_to_status_code(status_code) + span.set_status(http_status_code) + + if http_status_code == StatusCode.ERROR and _report_new(semconv): + # http semconv transition: new error.type + span_attributes[ERROR_TYPE] = str(status_code) + + if http_version and _report_new(semconv): + # http semconv transition: http.flavor -> network.protocol.version + _set_http_network_protocol_version( + span_attributes, + http_version.replace("HTTP/", ""), + semconv, + ) + + for key, val in span_attributes.items(): + span.set_attribute(key, val) + + class SyncOpenTelemetryTransport(httpx.BaseTransport): """Sync transport class that will trace all requests made with a client. @@ -318,12 +399,17 @@ def __init__( request_hook: typing.Optional[RequestHook] = None, response_hook: typing.Optional[ResponseHook] = None, ): + _OpenTelemetrySemanticConventionStability._initialize() + self._sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + self._transport = transport self._tracer = get_tracer( __name__, instrumenting_library_version=__version__, tracer_provider=tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(self._sem_conv_opt_in_mode), ) self._request_hook = request_hook self._response_hook = response_hook @@ -340,6 +426,7 @@ def __exit__( ) -> None: self._transport.__exit__(exc_type, exc_value, traceback) + # pylint: disable=R0914 def handle_request( self, *args, @@ -355,39 +442,64 @@ def handle_request( method, url, headers, stream, extensions = _extract_parameters( args, kwargs ) - span_attributes = _prepare_attributes(method, url) + method_original = method.decode() + span_name = _get_default_span_name(method_original) + span_attributes = {} + # apply http client response attributes according to semconv + _apply_request_client_attributes_to_span( + span_attributes, + url, + method_original, + span_name, + self._sem_conv_opt_in_mode, + ) request_info = RequestInfo(method, url, headers, stream, extensions) - span_name = _get_default_span_name( - span_attributes[SpanAttributes.HTTP_METHOD] - ) with self._tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes ) as span: - if self._request_hook is not None: + exception = None + if callable(self._request_hook): self._request_hook(span, request_info) _inject_propagation_headers(headers, args, kwargs) - response = self._transport.handle_request(*args, **kwargs) - if isinstance(response, httpx.Response): - response: httpx.Response = response - status_code = response.status_code - headers = response.headers - stream = response.stream - extensions = response.extensions - else: - status_code, headers, stream, extensions = response - - _apply_status_code(span, status_code) - - if self._response_hook is not None: - self._response_hook( - span, - request_info, - ResponseInfo(status_code, headers, stream, extensions), + + try: + response = self._transport.handle_request(*args, **kwargs) + except Exception as exc: # pylint: disable=W0703 + exception = exc + response = getattr(exc, "response", None) + + if isinstance(response, (httpx.Response, tuple)): + status_code, headers, stream, extensions, http_version = ( + _extract_response(response) ) + if span.is_recording(): + # apply http client response attributes according to semconv + _apply_response_client_attributes_to_span( + span, + status_code, + http_version, + self._sem_conv_opt_in_mode, + ) + if callable(self._response_hook): + self._response_hook( + span, + request_info, + ResponseInfo(status_code, headers, stream, extensions), + ) + + if exception: + if span.is_recording() and _report_new( + self._sem_conv_opt_in_mode + ): + span.set_attribute( + ERROR_TYPE, type(exception).__qualname__ + ) + raise exception.with_traceback(exception.__traceback__) + return response def close(self) -> None: @@ -413,12 +525,17 @@ def __init__( request_hook: typing.Optional[AsyncRequestHook] = None, response_hook: typing.Optional[AsyncResponseHook] = None, ): + _OpenTelemetrySemanticConventionStability._initialize() + self._sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + self._transport = transport self._tracer = get_tracer( __name__, instrumenting_library_version=__version__, tracer_provider=tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(self._sem_conv_opt_in_mode), ) self._request_hook = request_hook self._response_hook = response_hook @@ -435,6 +552,7 @@ async def __aexit__( ) -> None: await self._transport.__aexit__(exc_type, exc_value, traceback) + # pylint: disable=R0914 async def handle_async_request(self, *args, **kwargs) -> typing.Union[ typing.Tuple[int, "Headers", httpx.AsyncByteStream, dict], httpx.Response, @@ -446,41 +564,66 @@ async def handle_async_request(self, *args, **kwargs) -> typing.Union[ method, url, headers, stream, extensions = _extract_parameters( args, kwargs ) - span_attributes = _prepare_attributes(method, url) - - span_name = _get_default_span_name( - span_attributes[SpanAttributes.HTTP_METHOD] + method_original = method.decode() + span_name = _get_default_span_name(method_original) + span_attributes = {} + # apply http client response attributes according to semconv + _apply_request_client_attributes_to_span( + span_attributes, + url, + method_original, + span_name, + self._sem_conv_opt_in_mode, ) + request_info = RequestInfo(method, url, headers, stream, extensions) with self._tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes ) as span: - if self._request_hook is not None: + exception = None + if callable(self._request_hook): await self._request_hook(span, request_info) _inject_propagation_headers(headers, args, kwargs) - response = await self._transport.handle_async_request( - *args, **kwargs - ) - if isinstance(response, httpx.Response): - response: httpx.Response = response - status_code = response.status_code - headers = response.headers - stream = response.stream - extensions = response.extensions - else: - status_code, headers, stream, extensions = response - - _apply_status_code(span, status_code) - - if self._response_hook is not None: - await self._response_hook( - span, - request_info, - ResponseInfo(status_code, headers, stream, extensions), + try: + response = await self._transport.handle_async_request( + *args, **kwargs ) + except Exception as exc: # pylint: disable=W0703 + exception = exc + response = getattr(exc, "response", None) + + if isinstance(response, (httpx.Response, tuple)): + status_code, headers, stream, extensions, http_version = ( + _extract_response(response) + ) + + if span.is_recording(): + # apply http client response attributes according to semconv + _apply_response_client_attributes_to_span( + span, + status_code, + http_version, + self._sem_conv_opt_in_mode, + ) + + if callable(self._response_hook): + await self._response_hook( + span, + request_info, + ResponseInfo(status_code, headers, stream, extensions), + ) + + if exception: + if span.is_recording() and _report_new( + self._sem_conv_opt_in_mode + ): + span.set_attribute( + ERROR_TYPE, type(exception).__qualname__ + ) + raise exception.with_traceback(exception.__traceback__) return response diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/package.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/package.py index 4e548655b6..633e01c8b1 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/package.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/package.py @@ -14,3 +14,7 @@ _instruments = ("httpx >= 0.18.0",) + +_supports_metrics = False + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 06ad963ab0..84bab598e6 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=too-many-lines + import abc import asyncio import typing @@ -22,6 +24,10 @@ import opentelemetry.instrumentation.httpx from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.httpx import ( AsyncOpenTelemetryTransport, HTTPXClientInstrumentor, @@ -30,6 +36,21 @@ from opentelemetry.instrumentation.utils import suppress_http_instrumentation from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.sdk import resources +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PEER_ADDRESS, + NETWORK_PEER_PORT, + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import URL_FULL from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase @@ -100,6 +121,9 @@ async def _async_no_update_request_hook(span: "Span", request: "RequestInfo"): return 123 +# pylint: disable=too-many-public-methods + + # Using this wrapper class to have a base class for the tests while also not # angering pylint or mypy when calling methods not in the class when only # subclassing abc.ABC. @@ -112,15 +136,39 @@ class BaseTest(TestBase, metaclass=abc.ABCMeta): request_hook = staticmethod(_request_hook) no_update_request_hook = staticmethod(_no_update_request_hook) + # TODO: make this more explicit to tests # pylint: disable=invalid-name def setUp(self): super().setUp() + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + self.env_patch = mock.patch.dict( + "os.environ", + { + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, + }, + ) + self.env_patch.start() + _OpenTelemetrySemanticConventionStability._initialized = False respx.start() - respx.get(self.URL).mock(httpx.Response(200, text="Hello!")) + respx.get(self.URL).mock( + httpx.Response( + 200, + text="Hello!", + extensions={"http_version": b"HTTP/1.1"}, + ) + ) # pylint: disable=invalid-name def tearDown(self): super().tearDown() + self.env_patch.stop() respx.stop() def assert_span( @@ -169,6 +217,87 @@ def test_basic(self): span, opentelemetry.instrumentation.httpx ) + def test_basic_new_semconv(self): + url = "http://mock:8080/status/200" + respx.get(url).mock( + httpx.Response( + 200, + text="Hello!", + extensions={"http_version": b"HTTP/1.1"}, + ) + ) + result = self.perform_request(url) + self.assertEqual(result.text, "Hello!") + span = self.assert_span() + + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "GET") + + self.assertEqual( + span.instrumentation_scope.schema_url, + SpanAttributes.SCHEMA_URL, + ) + self.assertEqual( + span.attributes, + { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url, + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + HTTP_RESPONSE_STATUS_CODE: 200, + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_PORT: 8080, + NETWORK_PEER_PORT: 8080, + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.UNSET) + + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.httpx + ) + + def test_basic_both_semconv(self): + url = "http://mock:8080/status/200" # 8080 because httpx returns None for common ports (http, https, wss) + respx.get(url).mock(httpx.Response(200, text="Hello!")) + result = self.perform_request(url) + self.assertEqual(result.text, "Hello!") + span = self.assert_span() + + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "GET") + + self.assertEqual( + span.instrumentation_scope.schema_url, + SpanAttributes.SCHEMA_URL, + ) + + self.assertEqual( + span.attributes, + { + SpanAttributes.HTTP_METHOD: "GET", + HTTP_REQUEST_METHOD: "GET", + SpanAttributes.HTTP_URL: url, + URL_FULL: url, + SpanAttributes.HTTP_HOST: "mock", + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + SpanAttributes.NET_PEER_PORT: 8080, + SpanAttributes.HTTP_STATUS_CODE: 200, + HTTP_RESPONSE_STATUS_CODE: 200, + SpanAttributes.HTTP_FLAVOR: "1.1", + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_PORT: 8080, + NETWORK_PEER_PORT: 8080, + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.UNSET) + + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.httpx + ) + def test_basic_multiple(self): self.perform_request(self.URL) self.perform_request(self.URL) @@ -191,6 +320,48 @@ def test_not_foundbasic(self): trace.StatusCode.ERROR, ) + def test_not_foundbasic_new_semconv(self): + url_404 = "http://mock/status/404" + + with respx.mock: + respx.get(url_404).mock(httpx.Response(404)) + result = self.perform_request(url_404) + + self.assertEqual(result.status_code, 404) + span = self.assert_span() + self.assertEqual( + span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404 + ) + # new in semconv + self.assertEqual(span.attributes.get(ERROR_TYPE), "404") + + self.assertIs( + span.status.status_code, + trace.StatusCode.ERROR, + ) + + def test_not_foundbasic_both_semconv(self): + url_404 = "http://mock/status/404" + + with respx.mock: + respx.get(url_404).mock(httpx.Response(404)) + result = self.perform_request(url_404) + + self.assertEqual(result.status_code, 404) + span = self.assert_span() + self.assertEqual( + span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 404 + ) + self.assertEqual( + span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404 + ) + self.assertEqual(span.attributes.get(ERROR_TYPE), "404") + + self.assertIs( + span.status.status_code, + trace.StatusCode.ERROR, + ) + def test_suppress_instrumentation(self): with suppress_http_instrumentation(): result = self.perform_request(self.URL) @@ -245,6 +416,83 @@ def test_requests_basic_exception(self): span = self.assert_span() self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertIn("Exception", span.status.description) + self.assertEqual( + span.events[0].attributes["exception.type"], "Exception" + ) + self.assertIsNone(span.attributes.get(ERROR_TYPE)) + + def test_requests_basic_exception_new_semconv(self): + with respx.mock, self.assertRaises(Exception): + respx.get(self.URL).mock(side_effect=Exception) + self.perform_request(self.URL) + + span = self.assert_span() + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertIn("Exception", span.status.description) + self.assertEqual( + span.events[0].attributes["exception.type"], "Exception" + ) + self.assertEqual(span.attributes.get(ERROR_TYPE), "Exception") + + def test_requests_basic_exception_both_semconv(self): + with respx.mock, self.assertRaises(Exception): + respx.get(self.URL).mock(side_effect=Exception) + self.perform_request(self.URL) + + span = self.assert_span() + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertIn("Exception", span.status.description) + self.assertEqual( + span.events[0].attributes["exception.type"], "Exception" + ) + self.assertEqual(span.attributes.get(ERROR_TYPE), "Exception") + + def test_requests_timeout_exception_new_semconv(self): + url = "http://mock:8080/exception" + with respx.mock, self.assertRaises(httpx.TimeoutException): + respx.get(url).mock(side_effect=httpx.TimeoutException) + self.perform_request(url) + + span = self.assert_span() + self.assertEqual( + span.attributes, + { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url, + SERVER_ADDRESS: "mock", + SERVER_PORT: 8080, + NETWORK_PEER_PORT: 8080, + NETWORK_PEER_ADDRESS: "mock", + ERROR_TYPE: "TimeoutException", + }, + ) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + + def test_requests_timeout_exception_both_semconv(self): + url = "http://mock:8080/exception" + with respx.mock, self.assertRaises(httpx.TimeoutException): + respx.get(url).mock(side_effect=httpx.TimeoutException) + self.perform_request(url) + + span = self.assert_span() + self.assertEqual( + span.attributes, + { + SpanAttributes.HTTP_METHOD: "GET", + HTTP_REQUEST_METHOD: "GET", + SpanAttributes.HTTP_URL: url, + URL_FULL: url, + SpanAttributes.HTTP_HOST: "mock", + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + SpanAttributes.NET_PEER_PORT: 8080, + SERVER_PORT: 8080, + NETWORK_PEER_PORT: 8080, + ERROR_TYPE: "TimeoutException", + }, + ) + self.assertEqual(span.status.status_code, StatusCode.ERROR) def test_requests_timeout_exception(self): with respx.mock, self.assertRaises(httpx.TimeoutException): @@ -373,6 +621,28 @@ def test_not_recording(self): self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) + @respx.mock + def test_not_recording_not_set_attribute_in_exception_new_semconv( + self, + ): + respx.get(self.URL).mock(side_effect=httpx.TimeoutException) + with mock.patch("opentelemetry.trace.INVALID_SPAN") as mock_span: + transport = self.create_transport( + tracer_provider=trace.NoOpTracerProvider() + ) + client = self.create_client(transport) + mock_span.is_recording.return_value = False + try: + self.perform_request(self.URL, client=client) + except httpx.TimeoutException: + pass + + self.assert_span(None, 0) + self.assertFalse(mock_span.is_recording()) + self.assertTrue(mock_span.is_recording.called) + self.assertFalse(mock_span.set_attribute.called) + self.assertFalse(mock_span.set_status.called) + class BaseInstrumentorTest(BaseTest, metaclass=abc.ABCMeta): @abc.abstractmethod def create_client( From a9247774c41a8a948a887d5d420fd2421dfa01e5 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 3 Jul 2024 16:22:00 -0600 Subject: [PATCH 077/335] Point pylint to the package root directories (#2658) * Point pylint to the root directories Fixes #2657 * Use cd with instrumentations * Do the same for the rest of the components * Specify pylint configuration file * Fix tox lint for sio-pika * Fix commands for util-http and azure detector * Fix lint for sdk-extension-aws * Fix lint for opentelemetry-instrumentation * Fix lint for grpc instrumentation * Fix lint for opentelemetry-instrumentation --- .../tests/protobuf/test_server_pb2_grpc.py | 9 +- .../tests/auto_instrumentation/test_load.py | 14 +- .../test_benchmark_aws_xray_ids_generator.py | 4 +- .../tests/resource/test__lambda.py | 2 +- .../tests/resource/test_beanstalk.py | 2 +- .../tests/resource/test_ec2.py | 4 +- .../tests/resource/test_ecs.py | 16 +- .../tests/resource/test_eks.py | 4 +- tox.ini | 178 ++++++------------ 9 files changed, 98 insertions(+), 135 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/test_server_pb2_grpc.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/test_server_pb2_grpc.py index 003b68f4f1..3f848b8760 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/test_server_pb2_grpc.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/test_server_pb2_grpc.py @@ -12,6 +12,7 @@ def __init__(self, channel): Args: channel: A grpc.Channel. """ + # pylint: disable=invalid-name self.SimpleMethod = channel.unary_unary( "/GRPCTestServer/SimpleMethod", request_serializer=test__server__pb2.Request.SerializeToString, @@ -37,6 +38,9 @@ def __init__(self, channel): class GRPCTestServerServicer: """Missing associated documentation comment in .proto file""" + # pylint: disable=invalid-name + # pylint: disable=no-self-use + def SimpleMethod(self, request, context): """Missing associated documentation comment in .proto file""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -62,7 +66,9 @@ def BidirectionalStreamingMethod(self, request_iterator, context): raise NotImplementedError("Method not implemented!") -def add_GRPCTestServerServicer_to_server(servicer, server): +def add_GRPCTestServerServicer_to_server( + servicer, server +): # pylint: disable=invalid-name rpc_method_handlers = { "SimpleMethod": grpc.unary_unary_rpc_method_handler( servicer.SimpleMethod, @@ -95,6 +101,7 @@ def add_GRPCTestServerServicer_to_server(servicer, server): class GRPCTestServer: """Missing associated documentation comment in .proto file""" + # pylint: disable=invalid-name @staticmethod def SimpleMethod( request, diff --git a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py index 1e2a851e48..5fc59b542d 100644 --- a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py +++ b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py @@ -32,7 +32,9 @@ class TestLoad(TestCase): @patch( "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" ) - def test_load_configurators(self, iter_mock): + def test_load_configurators( + self, iter_mock + ): # pylint: disable=no-self-use # Add multiple entry points but only specify the 2nd in the environment variable. ep_mock1 = Mock() ep_mock1.name = "custom_configurator1" @@ -62,9 +64,8 @@ def test_load_configurators(self, iter_mock): "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" ) def test_load_configurators_no_ep( - self, - iter_mock, - ): + self, iter_mock + ): # pylint: disable=no-self-use iter_mock.return_value = () # Confirm method does not crash if not entry points exist. _load._load_configurators() @@ -214,6 +215,7 @@ def test_load_distro_error(self, iter_mock, isinstance_mock): ) def test_load_instrumentors(self, iter_mock, dep_mock): # Mock opentelemetry_pre_instrument entry points + # pylint: disable=too-many-locals pre_ep_mock1 = Mock() pre_ep_mock1.name = "pre1" pre_mock1 = Mock() @@ -285,7 +287,9 @@ def test_load_instrumentors(self, iter_mock, dep_mock): @patch( "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" ) - def test_load_instrumentors_dep_conflict(self, iter_mock, dep_mock): + def test_load_instrumentors_dep_conflict( + self, iter_mock, dep_mock + ): # pylint: disable=no-self-use ep_mock1 = Mock() ep_mock1.name = "instr1" diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py index c518755c60..573b3ee437 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from opentelemetry.sdk.extension.aws.trace import AwsXRayIdGenerator +from opentelemetry.sdk.extension.aws.trace import ( # pylint: disable=no-name-in-module + AwsXRayIdGenerator, +) id_generator = AwsXRayIdGenerator() diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test__lambda.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test__lambda.py index d23df95ebb..e183525e49 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test__lambda.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test__lambda.py @@ -16,7 +16,7 @@ from collections import OrderedDict from unittest.mock import patch -from opentelemetry.sdk.extension.aws.resource._lambda import ( +from opentelemetry.sdk.extension.aws.resource._lambda import ( # pylint: disable=no-name-in-module AwsLambdaResourceDetector, ) from opentelemetry.semconv.resource import ( diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py index 08def19002..29db8e459c 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py @@ -16,7 +16,7 @@ from collections import OrderedDict from unittest.mock import mock_open, patch -from opentelemetry.sdk.extension.aws.resource.beanstalk import ( +from opentelemetry.sdk.extension.aws.resource.beanstalk import ( # pylint: disable=no-name-in-module AwsBeanstalkResourceDetector, ) from opentelemetry.semconv.resource import ( diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py index 530fb75b48..300f963ac5 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py @@ -16,7 +16,9 @@ from collections import OrderedDict from unittest.mock import patch -from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector +from opentelemetry.sdk.extension.aws.resource.ec2 import ( # pylint: disable=no-name-in-module + AwsEc2ResourceDetector, +) from opentelemetry.semconv.resource import ( CloudPlatformValues, CloudProviderValues, diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py index 0ef77ad49e..4f892cc1bb 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import unittest from collections import OrderedDict +from os.path import dirname, join from unittest.mock import mock_open, patch -from opentelemetry.sdk.extension.aws.resource.ecs import AwsEcsResourceDetector +from opentelemetry.sdk.extension.aws.resource.ecs import ( # pylint: disable=no-name-in-module + AwsEcsResourceDetector, +) from opentelemetry.semconv.resource import ( CloudPlatformValues, CloudProviderValues, @@ -33,8 +35,10 @@ def _read_file(filename: str) -> str: - with open(os.path.join(os.path.dirname(__file__), "ecs", filename)) as f: - return f.read() + with open( + join(dirname(__file__), "ecs", filename), encoding="utf-8" + ) as file: + return file.read() MetadataV4Uri = "mock-uri-4" @@ -63,6 +67,7 @@ def _http_get_function_ec2(url: str, *args, **kwargs) -> str: return MetadataV4ContainerResponseEc2 if url == f"{MetadataV4Uri}/task": return MetadataV4TaskResponseEc2 + return None def _http_get_function_fargate(url: str, *args, **kwargs) -> str: @@ -70,6 +75,7 @@ def _http_get_function_fargate(url: str, *args, **kwargs) -> str: return MetadataV4ContainerResponseFargate if url == f"{MetadataV4Uri}/task": return MetadataV4TaskResponseFargate + return None class AwsEcsResourceDetectorTest(unittest.TestCase): @@ -150,7 +156,6 @@ def test_simple_create_metadata_v4_launchtype_ec2( ): mock_http_get_function.side_effect = _http_get_function_ec2 actual = AwsEcsResourceDetector().detect() - self.maxDiff = None self.assertDictEqual( actual.attributes.copy(), OrderedDict( @@ -215,7 +220,6 @@ def test_simple_create_metadata_v4_launchtype_fargate( ): mock_http_get_function.side_effect = _http_get_function_fargate actual = AwsEcsResourceDetector().detect() - self.maxDiff = None self.assertDictEqual( actual.attributes.copy(), OrderedDict( diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py index 5edb9c5352..a3819e6383 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py @@ -16,7 +16,9 @@ from collections import OrderedDict from unittest.mock import mock_open, patch -from opentelemetry.sdk.extension.aws.resource.eks import AwsEksResourceDetector +from opentelemetry.sdk.extension.aws.resource.eks import ( # pylint: disable=no-name-in-module + AwsEksResourceDetector, +) from opentelemetry.semconv.resource import ( CloudPlatformValues, CloudProviderValues, diff --git a/tox.ini b/tox.ini index b4d5203b9f..7341b7e5b0 100644 --- a/tox.ini +++ b/tox.ini @@ -382,6 +382,7 @@ deps = ; FIXME: add coverage testing ; FIXME: add mypy testing +allowlist_externals = sh setenv = ; override CORE_REPO_SHA via env variable when testing other branches/commits than main @@ -789,414 +790,355 @@ commands = lint-distro: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-distro lint-distro: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-distro lint-distro: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-distro - lint-distro: pylint {toxinidir}/opentelemetry-distro/src/opentelemetry - lint-distro: pylint {toxinidir}/opentelemetry-distro/tests + lint-distro: pylint {toxinidir}/opentelemetry-distro test-opentelemetry-instrumentation: pytest {toxinidir}/opentelemetry-instrumentation/tests {posargs} lint-opentelemetry-instrumentation: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-instrumentation lint-opentelemetry-instrumentation: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-instrumentation lint-opentelemetry-instrumentation: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-instrumentation - lint-opentelemetry-instrumentation: pylint {toxinidir}/opentelemetry-instrumentation/src/opentelemetry - lint-opentelemetry-instrumentation: pylint {toxinidir}/opentelemetry-instrumentation/tests + lint-opentelemetry-instrumentation: pylint {toxinidir}/opentelemetry-instrumentation test-instrumentation-aiohttp-client: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests {posargs} lint-instrumentation-aiohttp-client: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client - lint-instrumentation-aiohttp-client: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry - lint-instrumentation-aiohttp-client: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests + lint-instrumentation-aiohttp-client: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiohttp-client" test-instrumentation-aiohttp-server: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests {posargs} lint-instrumentation-aiohttp-server: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server - lint-instrumentation-aiohttp-server: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry - lint-instrumentation-aiohttp-server: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests + lint-instrumentation-aiohttp-server: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiohttp-server" test-instrumentation-aiopg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/tests {posargs} lint-instrumentation-aiopg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg lint-instrumentation-aiopg: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg lint-instrumentation-aiopg: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg - lint-instrumentation-aiopg: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry - lint-instrumentation-aiopg: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/tests + lint-instrumentation-aiopg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiopg" test-instrumentation-asgi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/tests {posargs} lint-instrumentation-asgi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi lint-instrumentation-asgi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi lint-instrumentation-asgi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi - lint-instrumentation-asgi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry - lint-instrumentation-asgi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/tests + lint-instrumentation-asgo: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asgi test-instrumentation-asyncpg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/tests {posargs} lint-instrumentation-asyncpg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg lint-instrumentation-asyncpg: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg lint-instrumentation-asyncpg: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg - lint-instrumentation-asyncpg: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry - lint-instrumentation-asyncpg: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/tests + lint-instrumentation-asyncpg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asyncpg" test-instrumentation-aws-lambda: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/tests {posargs} lint-instrumentation-aws-lambda: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda lint-instrumentation-aws-lambda: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda lint-instrumentation-aws-lambda: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda - lint-instrumentation-aws-lambda: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry - lint-instrumentation-aws-lambda: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/tests + lint-instrumentation-aws-lambda: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aws-lambda" test-instrumentation-boto: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/tests {posargs} lint-instrumentation-boto: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-boto lint-instrumentation-boto: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-boto lint-instrumentation-boto: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-boto - lint-instrumentation-boto: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry - lint-instrumentation-boto: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/tests + lint-instrumentation-boto: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-boto" test-instrumentation-botocore: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/tests {posargs} lint-instrumentation-botocore: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore lint-instrumentation-botocore: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore lint-instrumentation-botocore: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore - lint-instrumentation-botocore: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry - lint-instrumentation-botocore: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/tests + lint-instrumentation-botocore: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-botocore" test-instrumentation-boto3sqs: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/tests {posargs} lint-instrumentation-boto3sqs: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs lint-instrumentation-boto3sqs: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs lint-instrumentation-boto3sqs: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs - lint-instrumentation-boto3sqs: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry - lint-instrumentation-boto3sqs: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/tests + lint-instrumentation-boto3sqs: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-boto3sqs" test-instrumentation-cassandra: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/tests {posargs} lint-instrumentation-cassandra: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra lint-instrumentation-cassandra: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra lint-instrumentation-cassandra: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra - lint-instrumentation-cassandra: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry - lint-instrumentation-cassandra: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/tests + lint-instrumentation-cassandra: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-cassandra" test-instrumentation-celery: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/tests {posargs} lint-instrumentation-celery: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-celery lint-instrumentation-celery: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-celery lint-instrumentation-celery: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-celery - lint-instrumentation-celery: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry - lint-instrumentation-celery: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/tests + lint-instrumentation-celery: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-celery" test-instrumentation-dbapi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/tests {posargs} lint-instrumentation-dbapi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi lint-instrumentation-dbapi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi lint-instrumentation-dbapi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi - lint-instrumentation-dbapi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry - lint-instrumentation-dbapi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/tests + lint-instrumentation-dbapi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-dbapi" test-instrumentation-django: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-django/tests {posargs} lint-instrumentation-django: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-django lint-instrumentation-django: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-django lint-instrumentation-django: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-django - lint-instrumentation-django: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry - lint-instrumentation-django: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-django/tests + lint-instrumentation-django: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-django" test-instrumentation-elasticsearch: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/tests {posargs} lint-instrumentation-elasticsearch: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch lint-instrumentation-elasticsearch: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch lint-instrumentation-elasticsearch: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch - lint-instrumentation-elasticsearch: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry - lint-instrumentation-elasticsearch: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/tests + lint-instrumentation-elasticsearch: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-elasticsearch" test-instrumentation-falcon: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/tests {posargs} lint-instrumentation-falcon: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon lint-instrumentation-falcon: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon lint-instrumentation-falcon: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon - lint-instrumentation-falcon: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry - lint-instrumentation-falcon: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/tests + lint-instrumentation-falcon: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-falcon" test-instrumentation-fastapi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/tests {posargs} lint-instrumentation-fastapi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi lint-instrumentation-fastapi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi lint-instrumentation-fastapi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi - lint-instrumentation-fastapi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry - lint-instrumentation-fastapi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/tests + lint-instrumentation-fastapi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-fastapi" test-instrumentation-flask: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/tests {posargs} lint-instrumentation-flask: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-flask lint-instrumentation-flask: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-flask lint-instrumentation-flask: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-flask - lint-instrumentation-flask: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry - lint-instrumentation-flask: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/tests + lint-instrumentation-flask: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-flask" test-instrumentation-urllib: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib/tests {posargs} lint-instrumentation-urllib: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib lint-instrumentation-urllib: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib lint-instrumentation-urllib: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib - lint-instrumentation-urllib: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry - lint-instrumentation-urllib: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib/tests + lint-instrumentation-urllib: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-urllib" test-instrumentation-urllib3: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/tests {posargs} lint-instrumentation-urllib3: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3 lint-instrumentation-urllib3: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3 lint-instrumentation-urllib3: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3 - lint-instrumentation-urllib3: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry - lint-instrumentation-urllib3: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/tests + lint-instrumentation-urllib3: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-urllib3" test-instrumentation-grpc: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/tests {posargs} lint-instrumentation-grpc: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc lint-instrumentation-grpc: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc lint-instrumentation-grpc: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc - lint-instrumentation-grpc: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry - lint-instrumentation-grpc: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/tests + lint-instrumentation-grpc: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-grpc" test-instrumentation-jinja2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2/tests {posargs} lint-instrumentation-jinja2: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 lint-instrumentation-jinja2: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 lint-instrumentation-jinja2: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 - lint-instrumentation-jinja2: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry - lint-instrumentation-jinja2: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2/tests + lint-instrumentation-jinja2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-jinja2" test-instrumentation-kafka-python: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/tests {posargs} lint-instrumentation-kafka-python: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python lint-instrumentation-kafka-python: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python lint-instrumentation-kafka-python: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python - lint-instrumentation-kafka-python: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry - lint-instrumentation-kafka-python: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/tests + lint-instrumentation-kafka-python: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-kafka-python" test-instrumentation-confluent-kafka: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests {posargs} lint-instrumentation-confluent-kafka: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka - lint-instrumentation-confluent-kafka: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry - lint-instrumentation-confluent-kafka: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests + lint-instrumentation-confluent-kafka: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-confluent-kafka" test-instrumentation-logging: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/tests {posargs} lint-instrumentation-logging: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-logging lint-instrumentation-logging: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-logging lint-instrumentation-logging: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-logging - lint-instrumentation-logging: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry - lint-instrumentation-logging: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/tests + lint-instrumentation-logging: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-logging" test-instrumentation-mysql: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/tests {posargs} lint-instrumentation-mysql: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql lint-instrumentation-mysql: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql lint-instrumentation-mysql: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql - lint-instrumentation-mysql: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry - lint-instrumentation-mysql: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/tests + lint-instrumentation-mysql: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysql" test-instrumentation-mysqlclient: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/tests {posargs} lint-instrumentation-mysqlclient: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient lint-instrumentation-mysqlclient: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient lint-instrumentation-mysqlclient: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient - lint-instrumentation-mysqlclient: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry - lint-instrumentation-mysqlclient: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/tests + lint-instrumentation-mysqliclient: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysqliclient" test-instrumentation-sio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests {posargs} lint-instrumentation-sio-pika: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pika lint-instrumentation-sio-pika: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pika lint-instrumentation-sio-pika: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pika - lint-instrumentation-sio-pika: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry - lint-instrumentation-sio-pika: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests + lint-instrumentation-sio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pika" test-instrumentation-aio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/tests {posargs} lint-instrumentation-aio-pika: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika lint-instrumentation-aio-pika: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika lint-instrumentation-aio-pika: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika - lint-instrumentation-aio-pika: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry - lint-instrumentation-aio-pika: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/tests + lint-instrumentation-aio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aio-pika" test-instrumentation-psycopg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/tests {posargs} lint-instrumentation-psycopg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg lint-instrumentation-psycopg: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg lint-instrumentation-psycopg: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg - lint-instrumentation-psycopg: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry - lint-instrumentation-psycopg: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/tests + lint-instrumentation-psycopg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-psycopg" test-instrumentation-psycopg2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/tests {posargs} lint-instrumentation-psycopg2: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 lint-instrumentation-psycopg2: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 lint-instrumentation-psycopg2: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 - lint-instrumentation-psycopg2: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry - lint-instrumentation-psycopg2: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/tests + lint-instrumentation-psycopg2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-psycopg2" test-instrumentation-pymemcache: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/tests {posargs} lint-instrumentation-pymemcache: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache lint-instrumentation-pymemcache: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache lint-instrumentation-pymemcache: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache - lint-instrumentation-pymemcache: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry - lint-instrumentation-pymemcache: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/tests + lint-instrumentation-pymemecache: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymemecache" test-instrumentation-pymongo: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/tests {posargs} lint-instrumentation-pymongo: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo lint-instrumentation-pymongo: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo lint-instrumentation-pymongo: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo - lint-instrumentation-pymongo: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry - lint-instrumentation-pymongo: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/tests + lint-instrumentation-pymongo: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymongo" test-instrumentation-pymysql: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/tests {posargs} lint-instrumentation-pymysql: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql lint-instrumentation-pymysql: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql lint-instrumentation-pymysql: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql - lint-instrumentation-pymysql: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry - lint-instrumentation-pymysql: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/tests + lint-instrumentation-pymysql: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymysql" test-instrumentation-pyramid: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid/tests {posargs} lint-instrumentation-pyramid: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid lint-instrumentation-pyramid: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid lint-instrumentation-pyramid: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid - lint-instrumentation-pyramid: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry - lint-instrumentation-pyramid: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid/tests + lint-instrumentation-pyramid: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pyramid" test-instrumentation-redis: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-redis/tests {posargs} lint-instrumentation-redis: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-redis lint-instrumentation-redis: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-redis lint-instrumentation-redis: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-redis - lint-instrumentation-redis: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry - lint-instrumentation-redis: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-redis/tests + lint-instrumentation-redis: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-redis" test-instrumentation-remoulade: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade/tests {posargs} lint-instrumentation-remoulade: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade lint-instrumentation-remoulade: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade lint-instrumentation-remoulade: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade - lint-instrumentation-remoulade: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry - lint-instrumentation-remoulade: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade/tests + lint-instrumentation-remoulade: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-remoulade" test-instrumentation-requests: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-requests/tests {posargs} lint-instrumentation-requests: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-requests lint-instrumentation-requests: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-requests lint-instrumentation-requests: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-requests - lint-instrumentation-requests: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry - lint-instrumentation-requests: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-requests/tests + lint-instrumentation-requests: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-requests" test-instrumentation-sklearn: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn/tests {posargs} lint-instrumentation-sklearn: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn lint-instrumentation-sklearn: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn lint-instrumentation-sklearn: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn - lint-instrumentation-sklearn: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry - lint-instrumentation-sklearn: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn/tests + lint-instrumentation-sklearn: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-sklearn" test-instrumentation-sqlalchemy: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests {posargs} lint-instrumentation-sqlalchemy: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy lint-instrumentation-sqlalchemy: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy lint-instrumentation-sqlalchemy: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy - lint-instrumentation-sqlalchemy: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry - lint-instrumentation-sqlalchemy: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests + lint-instrumentation-sqlalchemy: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-sqlalchemy" test-instrumentation-sqlite3: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3/tests {posargs} lint-instrumentation-sqlite3: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3 lint-instrumentation-sqlite3: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3 lint-instrumentation-sqlite3: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3 - lint-instrumentation-sqlite3: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry - lint-instrumentation-sqlite3: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3/tests + lint-instrumentation-sqlite3: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-sqlite3" test-instrumentation-starlette: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette/tests {posargs} lint-instrumentation-starlette: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette lint-instrumentation-starlette: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette lint-instrumentation-starlette: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette - lint-instrumentation-starlette: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry - lint-instrumentation-starlette: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette/tests + lint-instrumentation-starlette: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-starlette" test-instrumentation-system-metrics: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics/tests {posargs} lint-instrumentation-system-metrics: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics lint-instrumentation-system-metrics: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics lint-instrumentation-system-metrics: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics - lint-instrumentation-system-metrics: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry - lint-instrumentation-system-metrics: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics/tests + lint-instrumentation-system-metrics: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-system-metrics" test-instrumentation-threading: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-threading/tests {posargs} lint-instrumentation-threading: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-threading lint-instrumentation-threading: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-threading lint-instrumentation-threading: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-threading - lint-instrumentation-threading: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry - lint-instrumentation-threading: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-threading/tests + lint-instrumentation-threading: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-threading" test-instrumentation-tornado: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado/tests {posargs} lint-instrumentation-tornado: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado lint-instrumentation-tornado: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado lint-instrumentation-tornado: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado - lint-instrumentation-tornado: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry - lint-instrumentation-tornado: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado/tests + lint-instrumentation-tornado: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-tornado" test-instrumentation-tortoiseorm: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm/tests {posargs} lint-instrumentation-tortoiseorm: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm - lint-instrumentation-tortoiseorm: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry - lint-instrumentation-tortoiseorm: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm/tests + lint-instrumentation-tortoiseorm: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-tortoiseorm" test-instrumentation-wsgi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/tests {posargs} lint-instrumentation-wsgi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi lint-instrumentation-wsgi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi lint-instrumentation-wsgi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi - lint-instrumentation-wsgi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry - lint-instrumentation-wsgi: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/tests + lint-instrumentation-wsgi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-wsgi" test-instrumentation-httpx: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/tests {posargs} lint-instrumentation-httpx: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx lint-instrumentation-httpx: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx lint-instrumentation-httpx: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx - lint-instrumentation-httpx: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry - lint-instrumentation-httpx: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/tests + lint-instrumentation-httpx: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-httpx" test-instrumentation-asyncio: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/tests {posargs} lint-instrumentation-asyncio: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio lint-instrumentation-asyncio: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio lint-instrumentation-asyncio: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio - lint-instrumentation-asyncio: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry - lint-instrumentation-asyncio: pylint {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/tests + lint-instrumentation-asyncio: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asyncio" test-util-http: pytest {toxinidir}/util/opentelemetry-util-http/tests {posargs} lint-util-http: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/util/opentelemetry-util-http lint-util-http: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/util/opentelemetry-util-http lint-util-http: flake8 --config {toxinidir}/.flake8 {toxinidir}/util/opentelemetry-util-http - lint-util-http: pylint {toxinidir}/util/opentelemetry-util-http/src/opentelemetry - lint-util-http: pylint {toxinidir}/util/opentelemetry-util-http/tests + lint-util-http: sh -c "cd util && pylint --rcfile ../.pylintrc opentelemetry-util-http" test-sdk-extension-aws: pytest {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/tests {posargs} lint-sdk-extension-aws: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws lint-sdk-extension-aws: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws lint-sdk-extension-aws: flake8 --config {toxinidir}/.flake8 {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws - lint-sdk-extension-aws: pylint {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry - lint-sdk-extension-aws: pylint {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/tests + lint-sdk-extension-aws: sh -c "cd sdk-extension && pylint --rcfile ../.pylintrc opentelemetry-sdk-extension-aws" test-resource-detector-container: pytest {toxinidir}/resource/opentelemetry-resource-detector-container/tests {posargs} lint-resource-detector-container: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/resource/opentelemetry-resource-detector-container lint-resource-detector-container: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/resource/opentelemetry-resource-detector-container lint-resource-detector-container: flake8 --config {toxinidir}/.flake8 {toxinidir}/resource/opentelemetry-resource-detector-container - lint-resource-detector-container: pylint {toxinidir}/resource/opentelemetry-resource-detector-container/src/opentelemetry - lint-resource-detector-container: pylint {toxinidir}/resource/opentelemetry-resource-detector-container/tests + lint-resource-detector-container: sh -c "cd resource && pylint --rcfile ../.pylintrc opentelemetry-resource-detector-container" test-resource-detector-azure: pytest {toxinidir}/resource/opentelemetry-resource-detector-azure/tests {posargs} lint-resource-detector-azure: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/resource/opentelemetry-resource-detector-azure lint-resource-detector-azure: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/resource/opentelemetry-resource-detector-azure lint-resource-detector-azure: flake8 --config {toxinidir}/.flake8 {toxinidir}/resource/opentelemetry-resource-detector-azure - lint-resource-detector-azure: pylint {toxinidir}/resource/opentelemetry-resource-detector-azure/src/opentelemetry - lint-resource-detector-azure: pylint {toxinidir}/resource/opentelemetry-resource-detector-azure/tests + lint-resource-detector-azure: sh -c "cd resource && pylint --rcfile ../.pylintrc opentelemetry-resource-detector-azure" test-processor-baggage: pytest {toxinidir}/processor/opentelemetry-processor-baggage/tests {posargs} lint-processor-baggage: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/processor/opentelemetry-processor-baggage lint-processor-baggage: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/processor/opentelemetry-processor-baggage lint-processor-baggage: flake8 --config {toxinidir}/.flake8 {toxinidir}/processor/opentelemetry-processor-baggage - lint-processor-baggage: pylint {toxinidir}/processor/opentelemetry-processor-baggage/src/opentelemetry - lint-processor-baggage: pylint {toxinidir}/processor/opentelemetry-processor-baggage/tests + lint-processor-baggage: sh -c "cd processor && pylint --rcfile ../.pylintrc opentelemetry-processor-baggage" test-propagator-aws-xray: pytest {toxinidir}/propagator/opentelemetry-propagator-aws-xray/tests {posargs} lint-propagator-aws-xray: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-aws-xray lint-propagator-aws-xray: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-aws-xray lint-propagator-aws-xray: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-aws-xray - lint-propagator-aws-xray: pylint {toxinidir}/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry - lint-propagator-aws-xray: pylint {toxinidir}/propagator/opentelemetry-propagator-aws-xray/tests + lint-propagator-aws-xray: sh -c "cd propagator && pylint --rcfile ../.pylintrc opentelemetry-propagator-aws-xray" test-propagator-ot-trace: pytest {toxinidir}/propagator/opentelemetry-propagator-ot-trace/tests {posargs} lint-propagator-ot-trace: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-ot-trace lint-propagator-ot-trace: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-ot-trace lint-propagator-ot-trace: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-ot-trace - lint-propagator-ot-trace: pylint {toxinidir}/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry - lint-propagator-ot-trace: pylint {toxinidir}/propagator/opentelemetry-propagator-ot-trace/tests + lint-propagator-ot-trace: sh -c "cd propagator && pylint --rcfile ../.pylintrc opentelemetry-propagator-ot-trace" test-exporter-richconsole: pytest {toxinidir}/exporter/opentelemetry-exporter-richconsole/tests {posargs} lint-exporter-richconsole: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-richconsole lint-exporter-richconsole: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-richconsole lint-exporter-richconsole: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-richconsole - lint-exporter-richconsole: pylint {toxinidir}/exporter/opentelemetry-exporter-richconsole/src/opentelemetry - lint-exporter-richconsole: pylint {toxinidir}/exporter/opentelemetry-exporter-richconsole/tests + lint-exporter-richconsole: sh -c "cd exporter && pylint --rcfile ../.pylintrc opentelemetry-exporter-richconsole" test-exporter-prometheus-remote-write: pytest {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/tests {posargs} lint-exporter-prometheus-remote-write: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write - lint-exporter-prometheus-remote-write: pylint {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry - lint-exporter-prometheus-remote-write: pylint {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/tests + lint-exporter-prometheus-remote-write: sh -c "cd exporter && pylint --rcfile ../.pylintrc opentelemetry-exporter-prometheus-remote-write" coverage: {toxinidir}/scripts/coverage.sh From fcc67514f55ed4ce8caab7a5851c0a9f5ba0b022 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 3 Jul 2024 17:22:45 -0600 Subject: [PATCH 078/335] Do not run benchmark tests in CI (#2660) * Do not run benchmark tests in CI Fixes #2659 * Add benchmark skip * Update .github/workflows/test.yml Co-authored-by: Riccardo Magliocchetti --------- Co-authored-by: Riccardo Magliocchetti --- .github/workflows/instrumentations_0.yml | 2 +- .github/workflows/instrumentations_1.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index fb8df0dcbb..cf64e56656 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -127,4 +127,4 @@ jobs: ~/.cache/pip key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-json=${{ env.RUN_MATRIX_COMBINATION }}-benchmark.json + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-skip diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index bd6f1aa2bf..5da296efb3 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -60,4 +60,4 @@ jobs: ~/.cache/pip key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-json=${{ env.RUN_MATRIX_COMBINATION }}-benchmark.json + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-skip From c272e687744ac7a03d4f383f28d07856f5d7fd23 Mon Sep 17 00:00:00 2001 From: Bart Vanbrabant Date: Thu, 4 Jul 2024 01:47:04 +0200 Subject: [PATCH 079/335] Support cursor based queries (#2501) * Support cursor based queries * Add unit test * Start of a test case * Update tests * Mock out all connection stuff * Run black * Fix typo * Use old python * Run black on the tests * Add changelog * Fix sorting * Use python 3.8 as baseline --------- Co-authored-by: Diego Hurtado --- CHANGELOG.md | 2 + .../instrumentation/asyncpg/__init__.py | 72 ++++++++++++++++-- .../tests/test_asyncpg_wrapper.py | 73 ++++++++++++++++++- 3 files changed, 139 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5031bc905..09c3d5fbd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2573](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2573)) - `opentelemetry-instrumentation-confluent-kafka` Add support for version 2.4.0 of confluent_kafka ([#2616](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2616)) +- `opentelemetry-instrumentation-asyncpg` Add instrumentation to cursor based queries + ([#2501](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2501)) - `opentelemetry-instrumentation-confluent-kafka` Add support for produce purge ([#2638](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2638)) - `opentelemetry-instrumentation-httpx` Implement new semantic convention opt-in migration with stable http semantic conventions diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py index 798a5dc00b..ba76254aa8 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py @@ -127,15 +127,27 @@ def _instrument(self, **kwargs): "asyncpg.connection", method, self._do_execute ) - def _uninstrument(self, **__): for method in [ - "execute", - "executemany", - "fetch", - "fetchval", - "fetchrow", + "Cursor.fetch", + "Cursor.forward", + "Cursor.fetchrow", + "CursorIterator.__anext__", ]: - unwrap(asyncpg.Connection, method) + wrapt.wrap_function_wrapper( + "asyncpg.cursor", method, self._do_cursor_execute + ) + + def _uninstrument(self, **__): + for cls, methods in [ + ( + asyncpg.connection.Connection, + ("execute", "executemany", "fetch", "fetchval", "fetchrow"), + ), + (asyncpg.cursor.Cursor, ("forward", "fetch", "fetchrow")), + (asyncpg.cursor.CursorIterator, ("__anext__",)), + ]: + for method_name in methods: + unwrap(cls, method_name) async def _do_execute(self, func, instance, args, kwargs): exception = None @@ -170,3 +182,49 @@ async def _do_execute(self, func, instance, args, kwargs): span.set_status(Status(StatusCode.ERROR)) return result + + async def _do_cursor_execute(self, func, instance, args, kwargs): + """Wrap cursor based functions. For every call this will generate a new span.""" + exception = None + params = getattr(instance._connection, "_params", {}) + name = ( + instance._query + if instance._query + else params.get("database", "postgresql") + ) + + try: + # Strip leading comments so we get the operation name. + name = self._leading_comment_remover.sub("", name).split()[0] + except IndexError: + name = "" + + stop = False + with self._tracer.start_as_current_span( + f"CURSOR: {name}", + kind=SpanKind.CLIENT, + ) as span: + if span.is_recording(): + span_attributes = _hydrate_span_from_args( + instance._connection, + instance._query, + instance._args if self.capture_parameters else None, + ) + for attribute, value in span_attributes.items(): + span.set_attribute(attribute, value) + + try: + result = await func(*args, **kwargs) + except StopAsyncIteration: + # Do not show this exception to the span + stop = True + except Exception as exc: # pylint: disable=W0703 + exception = exc + raise + finally: + if span.is_recording() and exception is not None: + span.set_status(Status(StatusCode.ERROR)) + + if not stop: + return result + raise StopAsyncIteration diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py index 12aad0c6dc..7c88b9c005 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py @@ -1,4 +1,9 @@ -from asyncpg import Connection +import asyncio +from unittest import mock + +import pytest +from asyncpg import Connection, Record, cursor +from wrapt import ObjectProxy from opentelemetry.instrumentation.asyncpg import AsyncPGInstrumentor from opentelemetry.test.test_base import TestBase @@ -34,3 +39,69 @@ def test_duplicated_uninstrumentation(self): self.assertFalse( hasattr(method, "_opentelemetry_ext_asyncpg_applied") ) + + def test_cursor_instrumentation(self): + def assert_wrapped(assert_fnc): + for cls, methods in [ + (cursor.Cursor, ("forward", "fetch", "fetchrow")), + (cursor.CursorIterator, ("__anext__",)), + ]: + for method_name in methods: + method = getattr(cls, method_name, None) + assert_fnc( + isinstance(method, ObjectProxy), + f"{method} isinstance {type(method)}", + ) + + assert_wrapped(self.assertFalse) + AsyncPGInstrumentor().instrument() + assert_wrapped(self.assertTrue) + AsyncPGInstrumentor().uninstrument() + assert_wrapped(self.assertFalse) + + def test_cursor_span_creation(self): + """Test the cursor wrapper if it creates spans correctly.""" + + # Mock out all interaction with postgres + async def bind_mock(*args, **kwargs): + return [] + + async def exec_mock(*args, **kwargs): + return [], None, True + + conn = mock.Mock() + conn.is_closed = lambda: False + + conn._protocol = mock.Mock() + conn._protocol.bind = bind_mock + conn._protocol.execute = exec_mock + conn._protocol.bind_execute = exec_mock + conn._protocol.close_portal = bind_mock + + state = mock.Mock() + state.closed = False + + apg = AsyncPGInstrumentor() + apg.instrument(tracer_provider=self.tracer_provider) + + # init the cursor and fetch a single record + crs = cursor.Cursor(conn, "SELECT * FROM test", state, [], Record) + asyncio.run(crs._init(1)) + asyncio.run(crs.fetch(1)) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].name, "CURSOR: SELECT") + self.assertTrue(spans[0].status.is_ok) + + # Now test that the StopAsyncIteration of the cursor does not get recorded as an ERROR + crs_iter = cursor.CursorIterator( + conn, "SELECT * FROM test", state, [], Record, 1, 1 + ) + + with pytest.raises(StopAsyncIteration): + asyncio.run(crs_iter.__anext__()) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + self.assertEqual([span.status.is_ok for span in spans], [True, True]) From 75faaad9864f3e4b169f71e34de361732b788911 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 4 Jul 2024 16:04:53 -0600 Subject: [PATCH 080/335] Remove unnecessary dependencies (#2663) * Remove unnecessary dependencies Fixes #2661 * Separate runs * Remove dev-requirements from test environment * Try without negative if * Remove positive if * Remove if * Separate benchmark-containing packages in another file * Add missing test-requirements.txt file --- .github/workflows/instrumentations_0.yml | 4 +- .github/workflows/instrumentations_1.yml | 7 ++- .github/workflows/instrumentations_2.yml | 50 +++++++++++++++++++ .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-3.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-3.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-3.txt | 1 - .../test-requirements-4.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - opentelemetry-distro/test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 13 +++++ .../test-requirements.txt | 1 - tox.ini | 5 +- .../test-requirements.txt | 1 - 82 files changed, 69 insertions(+), 87 deletions(-) create mode 100644 .github/workflows/instrumentations_2.yml create mode 100644 resource/opentelemetry-resource-detector-azure/test-requirements.txt diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index cf64e56656..d85102f435 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -126,5 +126,5 @@ jobs: .tox ~/.cache/pip key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-skip + - name: run pytest without --benchmark-skip + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 5da296efb3..af311343df 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -25,6 +25,7 @@ jobs: matrix: python-version: [py38, py39, py310, py311, py312, pypy3] package: + # Only add here packages that do not have benchmark tests - "urllib" - "urllib3" - "wsgi" @@ -32,8 +33,6 @@ jobs: - "richconsole" - "psycopg" - "prometheus-remote-write" - - "sdk-extension-aws" - - "propagator-aws-xray" - "propagator-ot-trace" - "resource-detector-azure" - "resource-detector-container" @@ -59,5 +58,5 @@ jobs: .tox ~/.cache/pip key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-skip + - name: run pytest without --benchmark-skip + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/instrumentations_2.yml b/.github/workflows/instrumentations_2.yml new file mode 100644 index 0000000000..48e7e127c8 --- /dev/null +++ b/.github/workflows/instrumentations_2.yml @@ -0,0 +1,50 @@ +name: Contrib Repo Tests + +on: + push: + branches-ignore: + - 'release/*' + pull_request: +env: + CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e + +jobs: + instrumentations-2: + env: + # We use these variables to convert between tox and GHA version literals + py38: 3.8 + py39: 3.9 + py310: "3.10" + py311: "3.11" + py312: "3.12" + pypy3: pypy-3.8 + RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + python-version: [py38, py39, py310, py311, py312, pypy3] + package: + # Only add here packages that have benchmark tests + - "sdk-extension-aws" + - "propagator-aws-xray" + os: [ubuntu-20.04] + steps: + - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + - name: Set up Python ${{ env[matrix.python-version] }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env[matrix.python-version] }} + - name: Install tox + run: pip install tox + - name: Cache tox environment + # Preserves .tox directory between runs for faster installs + uses: actions/cache@v4 + with: + path: | + .tox + ~/.cache/pip + key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} + - name: run pytest with --benchmark-skip + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-skip diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index b41245cd1f..8b47ad4093 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -11,7 +11,6 @@ pluggy==1.5.0 protobuf==4.25.3 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-snappy==0.7.1 requests==2.32.3 tomli==2.0.1 diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index af50fa87e8..eaa7ac3afa 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -10,7 +10,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 Pygments==2.17.2 pytest==7.4.4 -pytest-benchmark==4.0.0 rich==13.7.1 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index 3744af85b1..d03f17a64a 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -11,7 +11,6 @@ pamqp==3.1.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index bb35e2e2ba..09c96cdcfb 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -11,7 +11,6 @@ pamqp==3.2.1 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 3b17c80c25..691fcc27f4 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -11,7 +11,6 @@ pamqp==3.2.1 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index 4ea66f8dd6..f14b2e0d61 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -11,7 +11,6 @@ pamqp==3.3.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index f597361598..3fff2f6f41 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -21,7 +21,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index fe7582a2bb..75d2363578 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -14,7 +14,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 pytest-aiohttp==1.0.5 pytest-asyncio==0.23.5 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 033cee4492..9474f62f43 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -10,7 +10,6 @@ pluggy==1.5.0 psycopg2-binary==2.9.9 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index 9411be3b90..5313cff55f 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index 4943fcc851..d9be806a58 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-asyncio==0.23.5 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index 2ef86b3d94..de992b55b2 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index b5168dc7fe..515b1929d1 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 54c8bb0558..fb49507cc2 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -20,7 +20,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pycparser==2.21 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 PyYAML==6.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index 54fcf790d7..2105a36c3c 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -9,7 +9,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 s3transfer==0.10.0 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index f9fe9abe8a..c9f23944a9 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -20,7 +20,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pycparser==2.21 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 PyYAML==6.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index f0d811982b..6004a5ee89 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -9,7 +9,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 PyYAML==6.0.1 scylla-driver==3.26.6 six==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index 3159fefaf8..1000a2e8b7 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -16,7 +16,6 @@ pluggy==1.5.0 prompt-toolkit==3.0.43 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 6012f89379..7bed7ab671 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -15,7 +15,6 @@ pluggy==1.5.0 prompt-toolkit==3.0.43 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 87387ded81..0f114fb9cd 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index d35a55f831..30df307b5c 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index a6162e7c00..5231354b50 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 pytz==2024.1 sqlparse==0.5.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index 58f5d5c88b..a2c4e1faf2 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 pytz==2024.1 sqlparse==0.5.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index ffc43f4023..5794660465 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index 92ebaa83e4..cf75a2cfc2 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index e6d9bb6f9d..1f1f3057a1 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index 12e3a1c229..60d7e24c76 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index f34d67d9c8..bfcb79883f 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -9,7 +9,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index f17ada63f4..78db2d39ec 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-mimeparse==1.6.0 six==1.16.0 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index 68b1aba13d..eb330346fb 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index 4b4f8e7c0d..32ac062fbb 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 2116980b3f..8a77bc34d8 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -18,7 +18,6 @@ py-cpuinfo==9.0.0 pydantic==2.6.2 pydantic_core==2.16.3 pytest==7.4.4 -pytest-benchmark==4.0.0 requests==2.32.3 sniffio==1.3.0 starlette==0.36.3 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index fad2f5e2b0..efa8b73f82 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -11,7 +11,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 Werkzeug==2.3.8 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index 919ee6d431..46b089632f 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -11,7 +11,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 Werkzeug==2.3.8 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 16d91d2058..846cff1a80 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -12,7 +12,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 Werkzeug==3.0.3 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt index d30aa5c5e9..e1f7108cfa 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt @@ -8,7 +8,6 @@ pluggy==1.5.0 protobuf==3.20.3 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index ca3a0908fa..a9f1a2aaef 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -13,7 +13,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 respx==0.17.1 rfc3986==1.5.0 sniffio==1.3.1 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index d3476cea4b..928f5d8621 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -13,7 +13,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 respx==0.20.2 sniffio==1.3.1 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index e547f9bd20..4978ab40a7 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index 2f7007f872..6a9909e570 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index b7fcdc3dee..e085e96c73 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt index 95cd6ab35f..889bfc50da 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index 78060fbccc..d6c6eba35f 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index b6aa239e0f..093ca640b7 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -7,7 +7,6 @@ pika==0.13.1 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index 334d08f537..7e7a31ff52 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -7,7 +7,6 @@ pika==1.3.2 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index d9e9b4de0b..ef2c7742a1 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -8,7 +8,6 @@ pluggy==1.5.0 psycopg==3.1.18 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index 9269a3c378..f857b2b939 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 psycopg==3.1.18 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index 28ad25715d..2424afe1ff 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 psycopg2==2.9.9 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index ddb06914f7..ebe17d4af6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==1.3.5 pytest==7.4.4 -pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index a6ad4d0248..5f1676077e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==2.2.2 pytest==7.4.4 -pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index 7405224a8d..e3887cb8b1 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==3.4.1 pytest==7.4.4 -pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index d817e70c59..26c4ebe02b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==3.4.2 pytest==7.4.4 -pytest-benchmark==4.0.0 six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index 606d79143c..cd80efe831 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pymemcache==4.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index 2fd3f4ed0e..32f46253ad 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -8,7 +8,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pymongo==4.6.3 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index 5f2d8b7783..6f5fe6b9af 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 PyMySQL==1.1.1 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 184b03fed4..ce646b601b 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -11,7 +11,6 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pyramid==2.0.2 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 translationstring==1.4 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 00b0a04b3e..3228d08752 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 redis==5.0.1 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index 0f6374b7ef..680df4cfa6 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 prometheus_client==0.20.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 python-dateutil==2.8.2 pytz==2024.1 remoulade==3.2.0 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index c5c8f84366..406e1d6c02 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -10,7 +10,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 typing_extensions==4.9.0 diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt index 885caae033..760871c1ec 100644 --- a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 scikit-learn==0.24.2 scipy==1.10.1 threadpoolctl==3.3.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index 04f4fe0c4b..f5a7c5243c 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -9,7 +9,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 readline==6.2.4.1 SQLAlchemy==1.1.18 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index 4e1620b772..63272a878e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -8,7 +8,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 SQLAlchemy==1.4.51 tomli==2.0.1 typing_extensions==4.10.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index 848f207c8c..f7db73a853 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index a582353901..27d107299d 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -14,7 +14,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 requests==2.32.3 sniffio==1.3.0 starlette==0.13.8 diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index 13573c65bd..943bdcc90d 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -7,7 +7,6 @@ pluggy==1.5.0 psutil==6.0.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index eb37259669..5526083a62 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 14ac028083..6318a7d8c6 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -16,7 +16,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 tornado==6.4.1 diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index 2d518c1192..0e9713f3f6 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -12,7 +12,6 @@ pydantic==2.6.2 pydantic_core==2.16.3 pypika-tortoise==0.1.6 pytest==7.4.4 -pytest-benchmark==4.0.0 pytz==2024.1 tomli==2.0.1 tortoise-orm==0.20.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index 0ac7842086..c60ea23c02 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index 6eb6272dbf..c3c7761ed3 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 urllib3==1.26.19 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 402beb85b9..783be267b1 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -7,7 +7,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.2 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index a25f8882d1..9c357965bf 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index b93758ee31..8cea2c2a3a 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index 2ef62218b1..f86c98d004 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index 59c30eabf4..a05528b67e 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements.txt b/resource/opentelemetry-resource-detector-azure/test-requirements.txt new file mode 100644 index 0000000000..13e58dc01f --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/test-requirements.txt @@ -0,0 +1,13 @@ +asgiref==3.7.2 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +typing_extensions==4.10.0 +wrapt==1.16.0 +zipp==3.17.0 +-e opentelemetry-instrumentation +-e resource/opentelemetry-resource-detector-azure diff --git a/resource/opentelemetry-resource-detector-container/test-requirements.txt b/resource/opentelemetry-resource-detector-container/test-requirements.txt index ecacb62b12..07dd186f30 100644 --- a/resource/opentelemetry-resource-detector-container/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-container/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 diff --git a/tox.ini b/tox.ini index 7341b7e5b0..0cd5094cb8 100644 --- a/tox.ini +++ b/tox.ini @@ -373,10 +373,7 @@ envlist = [testenv] deps = - -c dev-requirements.txt lint: -r dev-requirements.txt - test: pytest - test: pytest-benchmark coverage: pytest coverage: pytest-cov @@ -755,7 +752,7 @@ commands_pre = resource-detector-azure: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions resource-detector-azure: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk resource-detector-azure: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - resource-detector-azure: pip install -e {toxinidir}/resource/opentelemetry-resource-detector-azure -e {toxinidir}/opentelemetry-instrumentation + resource-detector-azure: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements.txt propagator-ot-trace: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api propagator-ot-trace: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions diff --git a/util/opentelemetry-util-http/test-requirements.txt b/util/opentelemetry-util-http/test-requirements.txt index 0e28bbdd05..cb1ffe135b 100644 --- a/util/opentelemetry-util-http/test-requirements.txt +++ b/util/opentelemetry-util-http/test-requirements.txt @@ -6,7 +6,6 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 -e opentelemetry-instrumentation \ No newline at end of file From c4c9b6b9a1ac5a7ae3cd1f3b2889dbe5dd633c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 5 Jul 2024 14:40:19 -0300 Subject: [PATCH 081/335] Add capture to open file descriptors in system metrics instrumentation (#2652) * add capture to open file descriptors in system metrics instrumentation * fix meter type * fix pypy test * add changelog entry * Update instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py Co-authored-by: Leighton Chen * remove runtiem prefix * update tests --------- Co-authored-by: Leighton Chen --- CHANGELOG.md | 2 ++ .../instrumentation/system_metrics/__init__.py | 18 ++++++++++++++++++ .../tests/test_system_metrics.py | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09c3d5fbd9..2adfc3ae32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2631](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2631)) - `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) +- `opentelemetry-instrumentation-system-metrics` Add support for capture open file descriptors + ([#2652](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2652)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index 6342d287d5..b7ffb25431 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -117,6 +117,7 @@ "process.runtime.thread_count": None, "process.runtime.cpu.utilization": None, "process.runtime.context_switches": ["involuntary", "voluntary"], + "process.open_file_descriptor.count": None, } if sys.platform == "darwin": @@ -169,6 +170,7 @@ def __init__( self._runtime_thread_count_labels = self._labels.copy() self._runtime_cpu_utilization_labels = self._labels.copy() self._runtime_context_switches_labels = self._labels.copy() + self._open_file_descriptor_count_labels = self._labels.copy() def instrumentation_dependencies(self) -> Collection[str]: return _instruments @@ -395,9 +397,25 @@ def _instrument(self, **kwargs): unit="switches", ) + if "process.open_file_descriptor.count" in self._config: + self._meter.create_observable_up_down_counter( + name="process.open_file_descriptor.count", + callbacks=[self._get_open_file_descriptors], + description="Number of file descriptors in use by the process.", + ) + def _uninstrument(self, **__): pass + def _get_open_file_descriptors( + self, options: CallbackOptions + ) -> Iterable[Observation]: + """Observer callback for Number of file descriptors in use by the process""" + yield Observation( + self._proc.num_fds(), + self._open_file_descriptor_count_labels.copy(), + ) + def _get_system_cpu_time( self, options: CallbackOptions ) -> Iterable[Observation]: diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py index 3986a32c16..1d6f08892e 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py @@ -118,12 +118,13 @@ def test_system_metrics_instrument(self): f"process.runtime.{self.implementation}.thread_count", f"process.runtime.{self.implementation}.context_switches", f"process.runtime.{self.implementation}.cpu.utilization", + "process.open_file_descriptor.count", ] if self.implementation == "pypy": - self.assertEqual(len(metric_names), 20) - else: self.assertEqual(len(metric_names), 21) + else: + self.assertEqual(len(metric_names), 22) observer_names.append( f"process.runtime.{self.implementation}.gc_count", ) @@ -842,3 +843,14 @@ def test_runtime_cpu_percent(self, mock_process_cpu_percent): self._test_metrics( f"process.runtime.{self.implementation}.cpu.utilization", expected ) + + @mock.patch("psutil.Process.num_fds") + def test_open_file_descriptor_count(self, mock_process_num_fds): + mock_process_num_fds.configure_mock(**{"return_value": 3}) + + expected = [_SystemMetricsResult({}, 3)] + self._test_metrics( + "process.open_file_descriptor.count", + expected, + ) + mock_process_num_fds.assert_called() From 3518974d6ef45bef2f5a98f817140cad1d9198d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:07:11 -0300 Subject: [PATCH 082/335] Fix typos in tox.ini (#2666) --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 0cd5094cb8..4399ccc1e1 100644 --- a/tox.ini +++ b/tox.ini @@ -817,7 +817,7 @@ commands = lint-instrumentation-asgi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi lint-instrumentation-asgi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi lint-instrumentation-asgi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi - lint-instrumentation-asgo: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asgi + lint-instrumentation-asgi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asgi" test-instrumentation-asyncpg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/tests {posargs} lint-instrumentation-asyncpg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg @@ -979,7 +979,7 @@ commands = lint-instrumentation-pymemcache: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache lint-instrumentation-pymemcache: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache lint-instrumentation-pymemcache: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache - lint-instrumentation-pymemecache: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymemecache" + lint-instrumentation-pymemcache: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymemcache" test-instrumentation-pymongo: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/tests {posargs} lint-instrumentation-pymongo: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo From c8e529e43745521345cf0c4d405a27a8f7c4c8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:55:16 -0300 Subject: [PATCH 083/335] Update CHANGELOG.md (#2665) --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2adfc3ae32..3eddf58cb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2501](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2501)) - `opentelemetry-instrumentation-confluent-kafka` Add support for produce purge ([#2638](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2638)) +- `opentelemetry-instrumentation-asgi` Implement new semantic convention opt-in with stable http semantic conventions + ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) - `opentelemetry-instrumentation-httpx` Implement new semantic convention opt-in migration with stable http semantic conventions ([#2631](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2631)) - `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. @@ -33,10 +35,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Populate `{method}` as `HTTP` on `_OTHER` methods from scope ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) -### Added - -- `opentelemetry-instrumentation-asgi` Implement new semantic convention opt-in with stable http semantic conventions - ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) ### Fixed From 5ff46ac9d1596922112a57f328ae60c2eae6ae94 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 9 Jul 2024 17:17:00 -0600 Subject: [PATCH 084/335] Move benchmarks outside of tests directory (#2670) Fixes #2669 --- .github/workflows/instrumentations_0.yml | 2 +- .github/workflows/instrumentations_1.yml | 5 +- .github/workflows/instrumentations_2.yml | 50 ------------------- .gitignore | 3 ++ CONTRIBUTING.md | 8 ++- .../benchmark-requirements.txt | 1 + .../test_benchmark_aws_xray_propagator.py | 0 .../benchmark-requirements.txt | 1 + .../test_benchmark_aws_xray_ids_generator.py | 0 tox.ini | 6 +++ 10 files changed, 18 insertions(+), 58 deletions(-) delete mode 100644 .github/workflows/instrumentations_2.yml create mode 100644 propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt rename propagator/opentelemetry-propagator-aws-xray/{tests/performance => }/benchmarks/test_benchmark_aws_xray_propagator.py (100%) create mode 100644 sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt rename sdk-extension/opentelemetry-sdk-extension-aws/{tests/performance => }/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py (100%) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index d85102f435..d54cb50119 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -126,5 +126,5 @@ jobs: .tox ~/.cache/pip key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run pytest without --benchmark-skip + - name: run tox run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index af311343df..8c99eb0572 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -25,7 +25,6 @@ jobs: matrix: python-version: [py38, py39, py310, py311, py312, pypy3] package: - # Only add here packages that do not have benchmark tests - "urllib" - "urllib3" - "wsgi" @@ -33,6 +32,8 @@ jobs: - "richconsole" - "psycopg" - "prometheus-remote-write" + - "sdk-extension-aws" + - "propagator-aws-xray" - "propagator-ot-trace" - "resource-detector-azure" - "resource-detector-container" @@ -58,5 +59,5 @@ jobs: .tox ~/.cache/pip key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run pytest without --benchmark-skip + - name: run tox run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/instrumentations_2.yml b/.github/workflows/instrumentations_2.yml deleted file mode 100644 index 48e7e127c8..0000000000 --- a/.github/workflows/instrumentations_2.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Contrib Repo Tests - -on: - push: - branches-ignore: - - 'release/*' - pull_request: -env: - CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e - -jobs: - instrumentations-2: - env: - # We use these variables to convert between tox and GHA version literals - py38: 3.8 - py39: 3.9 - py310: "3.10" - py311: "3.11" - py312: "3.12" - pypy3: pypy-3.8 - RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - python-version: [py38, py39, py310, py311, py312, pypy3] - package: - # Only add here packages that have benchmark tests - - "sdk-extension-aws" - - "propagator-aws-xray" - os: [ubuntu-20.04] - steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - name: Set up Python ${{ env[matrix.python-version] }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env[matrix.python-version] }} - - name: Install tox - run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run pytest with --benchmark-skip - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra --benchmark-skip diff --git a/.gitignore b/.gitignore index c359e13727..1c32b4446a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ _build/ # mypy .mypy_cache/ target + +# Benchmark result files +*-benchmark.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f5a4913440..d7fc509c3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,9 +96,7 @@ for more detail on available tox commands. ### Benchmarks -Performance progression of benchmarks for packages distributed by OpenTelemetry Python can be viewed as a [graph of throughput vs commit history](https://opentelemetry-python-contrib.readthedocs.io/en/latest/performance/benchmarks.html). From the linked page, you can download a JSON file with the performance results. - -Running the `tox` tests also runs the performance tests if any are available. Benchmarking tests are done with `pytest-benchmark` and they output a table with results to the console. +Some packages have benchmark tests. To run them, run `tox -f benchmark`. Benchmark tests use `pytest-benchmark` and they output a table with results to the console. To write benchmarks, simply use the [pytest benchmark fixture](https://pytest-benchmark.readthedocs.io/en/latest/usage.html#usage) like the following: @@ -114,10 +112,10 @@ def test_simple_start_span(benchmark): benchmark(benchmark_start_as_current_span, "benchmarkedSpan", 42) ``` -Make sure the test file is under the `tests/performance/benchmarks/` folder of +Make sure the test file is under the `benchmarks/` folder of the package it is benchmarking and further has a path that corresponds to the file in the package it is testing. Make sure that the file name begins with -`test_benchmark_`. (e.g. `propagator/opentelemetry-propagator-aws-xray/tests/performance/benchmarks/trace/propagation/test_benchmark_aws_xray_propagator.py`) +`test_benchmark_`. (e.g. `propagator/opentelemetry-propagator-aws-xray/benchmarks/trace/propagation/test_benchmark_aws_xray_propagator.py`) ## Pull Requests diff --git a/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt new file mode 100644 index 0000000000..44564857ef --- /dev/null +++ b/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt @@ -0,0 +1 @@ +pytest-benchmark==4.0.0 diff --git a/propagator/opentelemetry-propagator-aws-xray/tests/performance/benchmarks/test_benchmark_aws_xray_propagator.py b/propagator/opentelemetry-propagator-aws-xray/benchmarks/test_benchmark_aws_xray_propagator.py similarity index 100% rename from propagator/opentelemetry-propagator-aws-xray/tests/performance/benchmarks/test_benchmark_aws_xray_propagator.py rename to propagator/opentelemetry-propagator-aws-xray/benchmarks/test_benchmark_aws_xray_propagator.py diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt new file mode 100644 index 0000000000..44564857ef --- /dev/null +++ b/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt @@ -0,0 +1 @@ +pytest-benchmark==4.0.0 diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py b/sdk-extension/opentelemetry-sdk-extension-aws/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py similarity index 100% rename from sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py rename to sdk-extension/opentelemetry-sdk-extension-aws/benchmarks/trace/test_benchmark_aws_xray_ids_generator.py diff --git a/tox.ini b/tox.ini index 4399ccc1e1..33f0242c5a 100644 --- a/tox.ini +++ b/tox.ini @@ -20,6 +20,7 @@ envlist = py3{8,9,10,11,12}-test-sdk-extension-aws pypy3-test-sdk-extension-aws lint-sdk-extension-aws + benchmark-sdk-extension-aws ; opentelemetry-distro py3{8,9,10,11,12}-test-distro @@ -314,6 +315,7 @@ envlist = py3{8,9,10,11,12}-test-propagator-aws-xray pypy3-test-propagator-aws-xray lint-propagator-aws-xray + benchmark-propagator-aws-xray ; opentelemetry-propagator-ot-trace py3{8,9,10,11,12}-test-propagator-ot-trace @@ -741,6 +743,7 @@ commands_pre = sdk-extension-aws: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk sdk-extension-aws: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt + benchmark-sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt resource-detector-container: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api resource-detector-container: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -765,6 +768,7 @@ commands_pre = propagator-aws-xray: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk propagator-aws-xray: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt + benchmark-propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt processor-baggage: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api processor-baggage: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -1094,6 +1098,7 @@ commands = lint-sdk-extension-aws: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws lint-sdk-extension-aws: flake8 --config {toxinidir}/.flake8 {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws lint-sdk-extension-aws: sh -c "cd sdk-extension && pylint --rcfile ../.pylintrc opentelemetry-sdk-extension-aws" + benchmark-sdk-extension-aws: pytest {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/benchmarks {posargs} --benchmark-json=sdk-extension-aws-benchmark.json test-resource-detector-container: pytest {toxinidir}/resource/opentelemetry-resource-detector-container/tests {posargs} lint-resource-detector-container: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/resource/opentelemetry-resource-detector-container @@ -1118,6 +1123,7 @@ commands = lint-propagator-aws-xray: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-aws-xray lint-propagator-aws-xray: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-aws-xray lint-propagator-aws-xray: sh -c "cd propagator && pylint --rcfile ../.pylintrc opentelemetry-propagator-aws-xray" + benchmark-propagator-aws-xray: pytest {toxinidir}/propagator/opentelemetry-propagator-aws-xray/benchmarks {posargs} --benchmark-json=propagator-aws-xray-benchmark.json test-propagator-ot-trace: pytest {toxinidir}/propagator/opentelemetry-propagator-ot-trace/tests {posargs} lint-propagator-ot-trace: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-ot-trace From 15fd1de93f9620d82861e0e5fec6a8c2325e7c52 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 10 Jul 2024 17:24:05 +0200 Subject: [PATCH 085/335] Bump certifi and zipp (#2689) * requirements: bump zipp to 3.19.2 To resolve a dependabot securiy report. * requirements: bump certifi to 2024.7.4 To resolve a dependabot security report. --- .../test-requirements.txt | 2 +- .../opentelemetry-exporter-richconsole/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-aiopg/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-asgi/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-boto/test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-dbapi/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-grpc/test-requirements.txt | 2 +- .../test-requirements-0.txt | 4 ++-- .../test-requirements-1.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-mysql/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-4.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-redis/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-wsgi/test-requirements.txt | 2 +- opentelemetry-distro/test-requirements.txt | 2 +- opentelemetry-instrumentation/test-requirements.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements.txt | 4 ++-- .../opentelemetry-propagator-ot-trace/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-sdk-extension-aws/test-requirements.txt | 2 +- 79 files changed, 89 insertions(+), 89 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 8b47ad4093..a32c442bf9 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -17,5 +17,5 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e exporter/opentelemetry-exporter-prometheus-remote-write diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index eaa7ac3afa..dee47c7880 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -14,5 +14,5 @@ rich==13.7.1 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e exporter/opentelemetry-exporter-richconsole diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index d03f17a64a..a08f6427db 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -15,6 +15,6 @@ tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 yarl==1.9.4 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-aio-pika diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index 09c96cdcfb..99b5fdfd1f 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -15,6 +15,6 @@ tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 yarl==1.9.4 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-aio-pika diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 691fcc27f4..7051299461 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -15,6 +15,6 @@ tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 yarl==1.9.4 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-aio-pika diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index f14b2e0d61..de5e8b310f 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -15,6 +15,6 @@ tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 yarl==1.9.4 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-aio-pika diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 3fff2f6f41..fd44fbbc62 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -3,7 +3,7 @@ aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 blinker==1.7.0 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 click==8.1.7 Deprecated==1.2.14 @@ -28,7 +28,7 @@ urllib3==2.2.2 Werkzeug==3.0.3 wrapt==1.16.0 yarl==1.9.4 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-aiohttp-client diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index 75d2363578..b83eff27f0 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -18,7 +18,7 @@ tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 yarl==1.9.4 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-aiohttp-server diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 9474f62f43..8a465a3326 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -13,7 +13,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-aiopg diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index 5313cff55f..ebe439d1d2 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -9,7 +9,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-asgi diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index d9be806a58..a196e8d4e3 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -10,6 +10,6 @@ pytest-asyncio==0.23.5 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-asyncio diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index de992b55b2..badc61cde8 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -11,6 +11,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-asyncpg diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index 515b1929d1..6540349a2e 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -9,7 +9,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e propagator/opentelemetry-propagator-aws-xray -e instrumentation/opentelemetry-instrumentation-aws-lambda diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index fb49507cc2..ab4819b538 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.7.2 boto==2.49.0 boto3==1.34.44 botocore==1.34.44 -certifi==2024.2.2 +certifi==2024.7.4 cffi==1.16.0 charset-normalizer==3.3.2 cryptography==42.0.5 @@ -33,6 +33,6 @@ urllib3==1.26.19 Werkzeug==2.3.8 wrapt==1.16.0 xmltodict==0.13.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-boto diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index 2105a36c3c..c5942b6a72 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -16,6 +16,6 @@ tomli==2.0.1 typing_extensions==4.9.0 urllib3==1.26.19 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-boto3sqs diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index c9f23944a9..e45fa6ba44 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.7.2 aws-xray-sdk==2.12.1 boto3==1.28.80 botocore==1.31.80 -certifi==2024.2.2 +certifi==2024.7.4 cffi==1.16.0 charset-normalizer==3.3.2 cryptography==42.0.5 @@ -33,7 +33,7 @@ urllib3==1.26.19 Werkzeug==3.0.3 wrapt==1.16.0 xmltodict==0.13.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e propagator/opentelemetry-propagator-aws-xray -e instrumentation/opentelemetry-instrumentation-botocore diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index 6004a5ee89..dc2090627d 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -15,6 +15,6 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-cassandra diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index 1000a2e8b7..401921f5e4 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -24,6 +24,6 @@ tzdata==2024.1 vine==5.1.0 wcwidth==0.2.13 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-celery diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 7bed7ab671..1c5aad2c07 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -23,6 +23,6 @@ tzdata==2024.1 vine==5.1.0 wcwidth==0.2.13 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-celery diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 0f114fb9cd..5400e507f5 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -10,6 +10,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-confluent-kafka diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index 30df307b5c..0d98d28069 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -9,6 +9,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index 5231354b50..5f22f2cadb 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -12,7 +12,7 @@ sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index a2c4e1faf2..0a042a1bf5 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -12,7 +12,7 @@ sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e instrumentation/opentelemetry-instrumentation-asgi diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 5794660465..9c78f42e46 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -12,7 +12,7 @@ sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e instrumentation/opentelemetry-instrumentation-asgi diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index cf75a2cfc2..77c049d87b 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -11,7 +11,7 @@ sqlparse==0.5.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e instrumentation/opentelemetry-instrumentation-asgi diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index 1f1f3057a1..07ea98e4d6 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -14,6 +14,6 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==1.26.19 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-elasticsearch diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index 60d7e24c76..228601485d 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -14,6 +14,6 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==1.26.19 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-elasticsearch diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index bfcb79883f..272675c119 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -15,6 +15,6 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-elasticsearch diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index 78db2d39ec..d0f6381b42 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -12,7 +12,7 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index eb330346fb..5a84f224f1 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index 32ac062fbb..0790e8a4cb 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 8a77bc34d8..00242d5410 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -1,7 +1,7 @@ annotated-types==0.6.0 anyio==4.3.0 asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 exceptiongroup==1.2.0 @@ -25,7 +25,7 @@ tomli==2.0.1 typing_extensions==4.9.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-asgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index efa8b73f82..a222e011a7 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -15,7 +15,7 @@ tomli==2.0.1 typing_extensions==4.9.0 Werkzeug==2.3.8 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index 46b089632f..e799218273 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -15,7 +15,7 @@ tomli==2.0.1 typing_extensions==4.9.0 Werkzeug==2.3.8 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 846cff1a80..91ae64700c 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -16,7 +16,7 @@ tomli==2.0.1 typing_extensions==4.9.0 Werkzeug==3.0.3 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt index e1f7108cfa..457c285715 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt @@ -11,6 +11,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-grpc diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index a9f1a2aaef..35ebe6b954 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -1,6 +1,6 @@ anyio==3.7.1 asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 Deprecated==1.2.14 exceptiongroup==1.2.0 h11==0.12.0 @@ -19,7 +19,7 @@ sniffio==1.3.1 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-httpx diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index 928f5d8621..c70677f06b 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -1,6 +1,6 @@ anyio==4.3.0 asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 Deprecated==1.2.14 exceptiongroup==1.2.0 h11==0.14.0 @@ -18,7 +18,7 @@ sniffio==1.3.1 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-httpx diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index 4978ab40a7..05d94d6fb0 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -11,6 +11,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-jinja2 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index 6a9909e570..4adc515de7 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -10,6 +10,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-kafka-python diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index e085e96c73..eca8ce5f34 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -9,6 +9,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-logging diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt index 889bfc50da..75ee9797b8 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-mysql diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index d6c6eba35f..534c7869cb 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-mysqlclient diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index 093ca640b7..cc874af2cc 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -10,6 +10,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pika diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index 7e7a31ff52..4a09147744 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -10,6 +10,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pika diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index ef2c7742a1..e60531b112 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -11,7 +11,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-psycopg diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index f857b2b939..6ad211f9c0 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-psycopg diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index 2424afe1ff..4d6682b3d6 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-psycopg2 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index ebe17d4af6..28a62d84b4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -11,6 +11,6 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pymemcache diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index 5f1676077e..4be0dbee52 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -11,6 +11,6 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pymemcache diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index e3887cb8b1..f07d79374a 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -11,6 +11,6 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pymemcache diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index 26c4ebe02b..4e4871147c 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -11,6 +11,6 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pymemcache diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index cd80efe831..28fe27f0ef 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -10,6 +10,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pymemcache diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index 32f46253ad..eb41ee6bd9 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -11,6 +11,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pymongo diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index 6f5fe6b9af..8338f79b65 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-pymysql diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index ce646b601b..56f89f8e8e 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -18,7 +18,7 @@ venusian==3.1.0 WebOb==1.8.7 Werkzeug==3.0.3 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 zope.deprecation==5.0 zope.interface==6.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 3228d08752..1731de082a 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -11,6 +11,6 @@ redis==5.0.1 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-redis diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index 680df4cfa6..727c15ec4e 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -14,6 +14,6 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-remoulade diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 406e1d6c02..03d0a793a6 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -1,5 +1,5 @@ asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 httpretty==1.1.4 @@ -15,7 +15,7 @@ tomli==2.0.1 typing_extensions==4.9.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-requests diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt index 760871c1ec..af341e16ed 100644 --- a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt @@ -14,6 +14,6 @@ threadpoolctl==3.3.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-sklearn diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index f5a7c5243c..af0e495a39 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -14,6 +14,6 @@ SQLAlchemy==1.1.18 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-sqlalchemy diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index 63272a878e..9b1b15debc 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -12,6 +12,6 @@ SQLAlchemy==1.4.51 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-sqlalchemy diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index f7db73a853..8c98e702b4 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -9,7 +9,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi -e instrumentation/opentelemetry-instrumentation-sqlite3 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 27d107299d..1d5b91e188 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -1,6 +1,6 @@ anyio==4.3.0 asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 exceptiongroup==1.2.0 @@ -21,7 +21,7 @@ tomli==2.0.1 typing_extensions==4.9.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-asgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index 943bdcc90d..506499ea13 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -10,6 +10,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-system-metrics diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index 5526083a62..45ee66cf01 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -9,6 +9,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-threading diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 6318a7d8c6..fb542966de 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -1,6 +1,6 @@ asgiref==3.7.2 blinker==1.7.0 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 click==8.1.7 Deprecated==1.2.14 @@ -23,7 +23,7 @@ typing_extensions==4.9.0 urllib3==2.2.2 Werkzeug==3.0.3 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-tornado diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index 0e9713f3f6..cb31845d66 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -17,6 +17,6 @@ tomli==2.0.1 tortoise-orm==0.20.0 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-tortoiseorm diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index c60ea23c02..9e11fb272f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -10,7 +10,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-urllib diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index c3c7761ed3..1d6ebc18af 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -11,7 +11,7 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==1.26.19 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-urllib3 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 783be267b1..06df34d16b 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -11,7 +11,7 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-urllib3 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index 9c357965bf..0f7c7ced73 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -9,7 +9,7 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http -e instrumentation/opentelemetry-instrumentation-wsgi diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index 8cea2c2a3a..d9190daa26 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -9,6 +9,6 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e opentelemetry-distro diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index f86c98d004..6cd12fad24 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -9,5 +9,5 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index 5e15e1c4a1..8589a794a4 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -1,5 +1,5 @@ asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 idna==3.7 @@ -15,5 +15,5 @@ tomli==2.0.1 typing_extensions==4.10.0 urllib3==2.2.2 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e propagator/opentelemetry-propagator-aws-xray diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index a05528b67e..0a72c3c823 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -9,5 +9,5 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e propagator/opentelemetry-propagator-ot-trace diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements.txt b/resource/opentelemetry-resource-detector-azure/test-requirements.txt index 13e58dc01f..028c41e65d 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements.txt @@ -8,6 +8,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e resource/opentelemetry-resource-detector-azure diff --git a/resource/opentelemetry-resource-detector-container/test-requirements.txt b/resource/opentelemetry-resource-detector-container/test-requirements.txt index 07dd186f30..8a926fff71 100644 --- a/resource/opentelemetry-resource-detector-container/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-container/test-requirements.txt @@ -9,5 +9,5 @@ pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e resource/opentelemetry-resource-detector-container diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt index 4ed081e748..27199627a1 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt @@ -10,5 +10,5 @@ pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.10.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e sdk-extension/opentelemetry-sdk-extension-aws From b1b9be0813e81f19567f6ce6234f60d44a4a39e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 10 Jul 2024 14:20:44 -0300 Subject: [PATCH 086/335] Fix lint-instrumentation-mysqlclient in tox.ini (#2691) --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 33f0242c5a..529e2a76c0 100644 --- a/tox.ini +++ b/tox.ini @@ -953,7 +953,7 @@ commands = lint-instrumentation-mysqlclient: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient lint-instrumentation-mysqlclient: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient lint-instrumentation-mysqlclient: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient - lint-instrumentation-mysqliclient: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysqliclient" + lint-instrumentation-mysqlclient: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysqlclient" test-instrumentation-sio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests {posargs} lint-instrumentation-sio-pika: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pika From 0b20c955faafbd12f661348a6362bb60077a64f2 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 10 Jul 2024 19:31:35 +0200 Subject: [PATCH 087/335] exporter/prometheus-remote-write: fix test requirements for pypy (#2692) --- .../test-requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index a32c442bf9..ec8f90336d 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -1,7 +1,9 @@ asgiref==3.7.2 certifi==2024.2.2 charset-normalizer==3.3.2 -cramjam==2.8.1 +# We can drop this after bumping baseline to pypy-39 +cramjam==2.1.0; platform_python_implementation == "PyPy" +cramjam==2.8.1; platform_python_implementation != "PyPy" Deprecated==1.2.14 idna==3.7 importlib-metadata==6.11.0 From 60fb936b7e5371b3e5587074906c49fb873cbd76 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 10 Jul 2024 20:34:39 +0200 Subject: [PATCH 088/335] instrumentation/asyncio: catch CancelledError exception in tests (#2690) * instrumentation/asyncio: catch CancelledError exception in tests After a29242f49386c097defce500b138dc00f06ce300 we are re-raising the CancelledError so we need to catch it on the caller side. Fix #2688 * instrument/asyncio: don't test anext on python < 3.10 Since it's not available there. * instrumentation/asyncio: use unittest.skipIf instead of reimplementing it --------- Co-authored-by: Leighton Chen --- .../tests/test_asyncio_anext.py | 5 ++ .../tests/test_asyncio_cancellation.py | 5 +- .../tests/test_asyncio_taskgroup.py | 13 ++--- .../tests/test_asyncio_to_thread.py | 55 ++++++++++--------- 4 files changed, 42 insertions(+), 36 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py index 9ce3fc4b33..e51f059ca0 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio +import sys +from unittest import skipIf from unittest.mock import patch # pylint: disable=no-name-in-module @@ -41,6 +43,9 @@ def tearDown(self): # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced. # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute. + @skipIf( + sys.version_info < (3, 10), "anext is only available in Python 3.10+" + ) def test_asyncio_anext(self): async def main(): async def async_gen(): diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_cancellation.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_cancellation.py index 9172cd4458..ca407391cc 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_cancellation.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_cancellation.py @@ -45,7 +45,10 @@ def tearDown(self): def test_cancel(self): with self._tracer.start_as_current_span("root", kind=SpanKind.SERVER): - asyncio.run(cancellation_create_task()) + try: + asyncio.run(cancellation_create_task()) + except asyncio.CancelledError: + pass spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 3) self.assertEqual(spans[0].context.trace_id, spans[1].context.trace_id) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_taskgroup.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_taskgroup.py index e02f63aa42..060f651b78 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_taskgroup.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_taskgroup.py @@ -13,6 +13,7 @@ # limitations under the License. import asyncio import sys +from unittest import skipIf from unittest.mock import patch # pylint: disable=no-name-in-module @@ -25,10 +26,6 @@ from .common_test_func import async_func -py11 = False -if sys.version_info >= (3, 11): - py11 = True - class TestAsyncioTaskgroup(TestBase): @patch.dict( @@ -46,11 +43,11 @@ def tearDown(self): super().tearDown() AsyncioInstrumentor().uninstrument() + @skipIf( + sys.version_info < (3, 11), + "TaskGroup is only available in Python 3.11+", + ) def test_task_group_create_task(self): - # TaskGroup is only available in Python 3.11+ - if not py11: - return - async def main(): async with asyncio.TaskGroup() as tg: # pylint: disable=no-member for _ in range(10): diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py index b53a6edc08..3d795d8ae7 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py @@ -13,6 +13,7 @@ # limitations under the License. import asyncio import sys +from unittest import skipIf from unittest.mock import patch # pylint: disable=no-name-in-module @@ -40,34 +41,34 @@ def tearDown(self): super().tearDown() AsyncioInstrumentor().uninstrument() + @skipIf( + sys.version_info < (3, 9), "to_thread is only available in Python 3.9+" + ) def test_to_thread(self): - # to_thread is only available in Python 3.9+ - if sys.version_info >= (3, 9): - - def multiply(x, y): - return x * y + def multiply(x, y): + return x * y - async def to_thread(): - result = await asyncio.to_thread(multiply, 2, 3) - assert result == 6 + async def to_thread(): + result = await asyncio.to_thread(multiply, 2, 3) + assert result == 6 - with self._tracer.start_as_current_span("root"): - asyncio.run(to_thread()) - spans = self.memory_exporter.get_finished_spans() + with self._tracer.start_as_current_span("root"): + asyncio.run(to_thread()) + spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 2) - assert spans[0].name == "asyncio to_thread-multiply" - for metric in ( - self.memory_metrics_reader.get_metrics_data() - .resource_metrics[0] - .scope_metrics[0] - .metrics - ): - if metric.name == "asyncio.process.duration": - for point in metric.data.data_points: - self.assertEqual(point.attributes["type"], "to_thread") - self.assertEqual(point.attributes["name"], "multiply") - if metric.name == "asyncio.process.created": - for point in metric.data.data_points: - self.assertEqual(point.attributes["type"], "to_thread") - self.assertEqual(point.attributes["name"], "multiply") + self.assertEqual(len(spans), 2) + assert spans[0].name == "asyncio to_thread-multiply" + for metric in ( + self.memory_metrics_reader.get_metrics_data() + .resource_metrics[0] + .scope_metrics[0] + .metrics + ): + if metric.name == "asyncio.process.duration": + for point in metric.data.data_points: + self.assertEqual(point.attributes["type"], "to_thread") + self.assertEqual(point.attributes["name"], "multiply") + if metric.name == "asyncio.process.created": + for point in metric.data.data_points: + self.assertEqual(point.attributes["type"], "to_thread") + self.assertEqual(point.attributes["name"], "multiply") From bbbe3ab7abe95b8a1689eafed9880b8d100321ee Mon Sep 17 00:00:00 2001 From: mspillane <37798417+mspillane@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:18:48 +0100 Subject: [PATCH 089/335] Add NoOpTracerProvider test for starlette (#2654) --- .../tests/test_starlette_instrumentation.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py index eed1a75c44..3f9f1c7b0f 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -398,6 +398,21 @@ def test_uninstrument(self): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) + def test_no_op_tracer_provider(self): + self._client.get("/foobar") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 3) + + self.memory_exporter.clear() + self._instrumentor.uninstrument() + + tracer_provider = NoOpTracerProvider() + self._instrumentor.instrument(tracer_provider=tracer_provider) + + self._client.get("/foobar") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + def test_sub_app_starlette_call(self): """ !!! Attention: we need to override this testcase for the auto-instrumented variant From 43dfc73c4c7cc1075739f341fbb56044e65ee0ee Mon Sep 17 00:00:00 2001 From: Zhihan Li <54661071+zhihali@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:34:59 +0100 Subject: [PATCH 090/335] add sync and async test guide at contributing.md (#2694) --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d7fc509c3a..8ab75ce1c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -269,6 +269,9 @@ Below is a checklist of things to be mindful of when implementing a new instrume - ex. - Appropriate error handling - ex. +- Isolate sync and async test + - For synchronous tests, the typical test case class is inherited from `opentelemetry.test.test_base.TestBase`. However, if you want to write asynchronous tests, the test case class should inherit also from `IsolatedAsyncioTestCase`. Adding asynchronous tests to a common test class can lead to tests passing without actually running, which can be misleading. + - ex. ## Expectations from contributors From b697f4ab9a3cf648ae004ef743b6e4564eaae6a2 Mon Sep 17 00:00:00 2001 From: Daniel Hochman Date: Fri, 12 Jul 2024 11:38:40 -0500 Subject: [PATCH 091/335] opentelemetry-instrumentation-asgi: always set status code on duration attributes (#2627) --- CHANGELOG.md | 2 + .../instrumentation/asgi/__init__.py | 50 +++++++-------- .../tests/test_asgi_middleware.py | 63 ++++++++++++++++++- .../opentelemetry/instrumentation/_semconv.py | 32 ++++++---- 4 files changed, 104 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eddf58cb8..76d77f06e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2153](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2153)) - `opentelemetry-instrumentation-asgi` Removed `NET_HOST_NAME` AND `NET_HOST_PORT` from active requests count attribute ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) +- `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. + ([#2627](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2627)) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index f006f9b0c9..7e51837d4d 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -438,8 +438,6 @@ def set_status_code( sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, ): """Adds HTTP response attributes to span using the status_code argument.""" - if not span.is_recording(): - return status_code_str = str(status_code) try: @@ -836,36 +834,16 @@ async def otel_send(message: dict[str, Any]): ) as send_span: if callable(self.client_response_hook): self.client_response_hook(send_span, scope, message) + + status_code = None + if message["type"] == "http.response.start": + status_code = message["status"] + elif message["type"] == "websocket.send": + status_code = 200 + if send_span.is_recording(): if message["type"] == "http.response.start": - status_code = message["status"] - # We record metrics only once - set_status_code( - server_span, - status_code, - duration_attrs, - self._sem_conv_opt_in_mode, - ) - set_status_code( - send_span, - status_code, - None, - self._sem_conv_opt_in_mode, - ) expecting_trailers = message.get("trailers", False) - elif message["type"] == "websocket.send": - set_status_code( - server_span, - 200, - duration_attrs, - self._sem_conv_opt_in_mode, - ) - set_status_code( - send_span, - 200, - None, - self._sem_conv_opt_in_mode, - ) send_span.set_attribute("asgi.event.type", message["type"]) if ( server_span.is_recording() @@ -886,6 +864,20 @@ async def otel_send(message: dict[str, Any]): server_span.set_attributes( custom_response_attributes ) + if status_code: + # We record metrics only once + set_status_code( + server_span, + status_code, + duration_attrs, + self._sem_conv_opt_in_mode, + ) + set_status_code( + send_span, + status_code, + None, + self._sem_conv_opt_in_mode, + ) propagator = get_global_response_propagator() if propagator: diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index ff266cb5bf..5bb04adb25 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -514,7 +514,9 @@ def test_asgi_not_recording(self): mock_span = mock.Mock() mock_span.is_recording.return_value = False mock_tracer.start_as_current_span.return_value = mock_span - mock_tracer.start_as_current_span.return_value.__enter__ = mock_span + mock_tracer.start_as_current_span.return_value.__enter__ = mock.Mock( + return_value=mock_span + ) mock_tracer.start_as_current_span.return_value.__exit__ = mock_span with mock.patch("opentelemetry.trace.get_tracer") as tracer: tracer.return_value = mock_tracer @@ -1342,6 +1344,65 @@ def test_basic_metric_success(self): ) self.assertEqual(point.value, 0) + def test_basic_metric_success_nonrecording_span(self): + mock_tracer = mock.Mock() + mock_span = mock.Mock() + mock_span.is_recording.return_value = False + mock_tracer.start_as_current_span.return_value = mock_span + mock_tracer.start_as_current_span.return_value.__enter__ = mock.Mock( + return_value=mock_span + ) + mock_tracer.start_as_current_span.return_value.__exit__ = mock_span + with mock.patch("opentelemetry.trace.get_tracer") as tracer: + tracer.return_value = mock_tracer + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + start = default_timer() + self.send_default_request() + duration = max(round((default_timer() - start) * 1000), 0) + expected_duration_attributes = { + "http.method": "GET", + "http.host": "127.0.0.1", + "http.scheme": "http", + "http.flavor": "1.0", + "net.host.port": 80, + "http.status_code": 200, + } + expected_requests_count_attributes = { + "http.method": "GET", + "http.host": "127.0.0.1", + "http.scheme": "http", + "http.flavor": "1.0", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + # pylint: disable=too-many-nested-blocks + for resource_metric in metrics_list.resource_metrics: + for scope_metrics in resource_metric.scope_metrics: + for metric in scope_metrics.metrics: + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) + self.assertEqual(point.count, 1) + if metric.name == "http.server.duration": + self.assertAlmostEqual( + duration, point.sum, delta=5 + ) + elif ( + metric.name == "http.server.response.size" + ): + self.assertEqual(1024, point.sum) + elif metric.name == "http.server.request.size": + self.assertEqual(128, point.sum) + elif isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + def test_basic_metric_success_new_semconv(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 85b8e2e3ec..7e81692a98 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -355,29 +355,35 @@ def _set_status( sem_conv_opt_in_mode, ): if status_code < 0: - if _report_new(sem_conv_opt_in_mode): - span.set_attribute(ERROR_TYPE, status_code_str) - metrics_attributes[ERROR_TYPE] = status_code_str - - span.set_status( - Status( - StatusCode.ERROR, - "Non-integer HTTP status: " + status_code_str, + metrics_attributes[ERROR_TYPE] = status_code_str + if span.is_recording(): + if _report_new(sem_conv_opt_in_mode): + span.set_attribute(ERROR_TYPE, status_code_str) + span.set_status( + Status( + StatusCode.ERROR, + "Non-integer HTTP status: " + status_code_str, + ) ) - ) else: status = http_status_to_status_code(status_code, server_span=True) if _report_old(sem_conv_opt_in_mode): - span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) + if span.is_recording(): + span.set_attribute( + SpanAttributes.HTTP_STATUS_CODE, status_code + ) metrics_attributes[SpanAttributes.HTTP_STATUS_CODE] = status_code if _report_new(sem_conv_opt_in_mode): - span.set_attribute(HTTP_RESPONSE_STATUS_CODE, status_code) + if span.is_recording(): + span.set_attribute(HTTP_RESPONSE_STATUS_CODE, status_code) metrics_attributes[HTTP_RESPONSE_STATUS_CODE] = status_code if status == StatusCode.ERROR: - span.set_attribute(ERROR_TYPE, status_code_str) + if span.is_recording(): + span.set_attribute(ERROR_TYPE, status_code_str) metrics_attributes[ERROR_TYPE] = status_code_str - span.set_status(Status(status)) + if span.is_recording(): + span.set_status(Status(status)) # Get schema version based off of opt-in mode From 5a2794692052deae7b70f66a95dbaafbe6dcba6c Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Fri, 12 Jul 2024 10:49:48 -0700 Subject: [PATCH 092/335] =?UTF-8?q?Add=20Em=C3=ADdio=20Neto=20as=20an=20ap?= =?UTF-8?q?prover=20(#2703)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6c019239ae..dcb2ebbba5 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,7 @@ Meeting notes are available as a public [Google doc](https://docs.google.com/doc Approvers ([@open-telemetry/python-approvers](https://github.com/orgs/open-telemetry/teams/python-approvers)): - [Aaron Abbott](https://github.com/aabmass), Google +- [Emídio Neto](https://github.com/emdneto), Zenvia - [Jeremy Voss](https://github.com/jeremydvoss), Microsoft - [Owais Lone](https://github.com/owais), Splunk - [Pablo Collins](https://github.com/pmcollins), Splunk From 6293d6a991d283b6d754d4736916db2d60ce8e5c Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Fri, 12 Jul 2024 11:48:04 -0700 Subject: [PATCH 093/335] HTTP semantic convention stability migration for fastapi (#2682) --- CHANGELOG.md | 7 +- instrumentation/README.md | 2 +- .../instrumentation/fastapi/__init__.py | 34 +- .../instrumentation/fastapi/package.py | 2 + .../tests/test_fastapi_instrumentation.py | 514 +++++++++++++++++- .../instrumentation/flask/__init__.py | 8 +- 6 files changed, 527 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76d77f06e0..b6882cbe57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2638](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2638)) - `opentelemetry-instrumentation-asgi` Implement new semantic convention opt-in with stable http semantic conventions ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) +- `opentelemetry-instrumentation-fastapi` Implement new semantic convention opt-in with stable http semantic conventions + ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) - `opentelemetry-instrumentation-httpx` Implement new semantic convention opt-in migration with stable http semantic conventions ([#2631](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2631)) - `opentelemetry-instrumentation-system-metrics` Permit to use psutil 6.0+. @@ -32,9 +34,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette` Use `tracer` and `meter` of originating components instead of one from `asgi` middleware ([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580)) -- Populate `{method}` as `HTTP` on `_OTHER` methods from scope +- Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `asgi` middleware ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) - + - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `fastapi` middleware + ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) ### Fixed diff --git a/instrumentation/README.md b/instrumentation/README.md index eb21717843..9add6d0228 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -19,7 +19,7 @@ | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental | [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 4.0.0 | Yes | experimental -| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | experimental +| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental | [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 4c673d214a..2f9bbe7314 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -177,6 +177,12 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A import fastapi from starlette.routing import Match +from opentelemetry.instrumentation._semconv import ( + _get_schema_url, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, +) from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.asgi.types import ( ClientRequestHook, @@ -189,7 +195,11 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry.metrics import get_meter from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import get_tracer -from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls +from opentelemetry.util.http import ( + get_excluded_urls, + parse_excluded_urls, + sanitize_method, +) _excluded_urls_from_env = get_excluded_urls("FASTAPI") _logger = logging.getLogger(__name__) @@ -218,6 +228,11 @@ def instrument_app( app._is_instrumented_by_opentelemetry = False if not getattr(app, "_is_instrumented_by_opentelemetry", False): + # initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) if excluded_urls is None: excluded_urls = _excluded_urls_from_env else: @@ -226,13 +241,13 @@ def instrument_app( __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) meter = get_meter( __name__, __version__, meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) app.add_middleware( @@ -303,6 +318,7 @@ class _InstrumentedFastAPI(fastapi.FastAPI): _client_request_hook: ClientRequestHook = None _client_response_hook: ClientResponseHook = None _instrumented_fastapi_apps = set() + _sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -310,13 +326,17 @@ def __init__(self, *args, **kwargs): __name__, __version__, _InstrumentedFastAPI._tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url( + _InstrumentedFastAPI._sem_conv_opt_in_mode + ), ) meter = get_meter( __name__, __version__, _InstrumentedFastAPI._meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url( + _InstrumentedFastAPI._sem_conv_opt_in_mode + ), ) self.add_middleware( OpenTelemetryMiddleware, @@ -373,8 +393,10 @@ def _get_default_span_details(scope): A tuple of span name and attributes """ route = _get_route_details(scope) - method = scope.get("method", "") + method = sanitize_method(scope.get("method", "").strip()) attributes = {} + if method == "_OTHER": + method = "HTTP" if route: attributes[SpanAttributes.HTTP_ROUTE] = route if method and route: # http diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py index 8df84fc931..d95a2cf6d5 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py @@ -16,3 +16,5 @@ _instruments = ("fastapi ~= 0.58",) _supports_metrics = True + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 0ad63164d5..69c5d312e5 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -11,6 +11,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +# pylint: disable=too-many-lines + import unittest from timeit import default_timer from unittest.mock import patch @@ -20,39 +23,77 @@ from fastapi.testclient import TestClient import opentelemetry.instrumentation.fastapi as otel_fastapi +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, + _server_active_requests_count_attrs_new, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new, + _server_duration_attrs_old, +) from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.sdk.metrics.export import ( HistogramDataPoint, NumberDataPoint, ) from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase -from opentelemetry.util.http import ( - _active_requests_count_attrs, - _duration_attrs, - get_excluded_urls, -) +from opentelemetry.util.http import get_excluded_urls -_expected_metric_names = [ +_expected_metric_names_old = [ "http.server.active_requests", "http.server.duration", "http.server.response.size", "http.server.request.size", ] -_recommended_attrs = { - "http.server.active_requests": _active_requests_count_attrs, - "http.server.duration": {*_duration_attrs, SpanAttributes.HTTP_TARGET}, +_expected_metric_names_new = [ + "http.server.active_requests", + "http.server.request.duration", + "http.server.response.body.size", + "http.server.request.body.size", +] +_expected_metric_names_both = _expected_metric_names_old +_expected_metric_names_both.extend(_expected_metric_names_new) + +_recommended_attrs_old = { + "http.server.active_requests": _server_active_requests_count_attrs_old, + "http.server.duration": { + *_server_duration_attrs_old, + SpanAttributes.HTTP_TARGET, + }, "http.server.response.size": { - *_duration_attrs, + *_server_duration_attrs_old, SpanAttributes.HTTP_TARGET, }, "http.server.request.size": { - *_duration_attrs, + *_server_duration_attrs_old, SpanAttributes.HTTP_TARGET, }, } +_recommended_attrs_new = { + "http.server.active_requests": _server_active_requests_count_attrs_new, + "http.server.request.duration": _server_duration_attrs_new, + "http.server.response.body.size": _server_duration_attrs_new, + "http.server.request.body.size": _server_duration_attrs_new, +} + +_recommended_attrs_both = _recommended_attrs_old.copy() +_recommended_attrs_both.update(_recommended_attrs_new) +_recommended_attrs_both["http.server.active_requests"].extend( + _server_active_requests_count_attrs_old +) + class TestBaseFastAPI(TestBase): def _create_app(self): @@ -88,10 +129,23 @@ def setUpClass(cls): def setUp(self): super().setUp() + + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" self.env_patch = patch.dict( "os.environ", - {"OTEL_PYTHON_FASTAPI_EXCLUDED_URLS": "/exclude/123,healthzz"}, + { + "OTEL_PYTHON_FASTAPI_EXCLUDED_URLS": "/exclude/123,healthzz", + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, + }, ) + _OpenTelemetrySemanticConventionStability._initialized = False self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.fastapi._excluded_urls_from_env", @@ -142,7 +196,6 @@ async def _(): class TestBaseManualFastAPI(TestBaseFastAPI): - @classmethod def setUpClass(cls): if cls is TestBaseManualFastAPI: @@ -196,7 +249,6 @@ def test_sub_app_fastapi_call(self): class TestBaseAutoFastAPI(TestBaseFastAPI): - @classmethod def setUpClass(cls): if cls is TestBaseAutoFastAPI: @@ -259,6 +311,7 @@ def test_sub_app_fastapi_call(self): ) +# pylint: disable=too-many-public-methods class TestFastAPIManualInstrumentation(TestBaseManualFastAPI): def test_instrument_app_with_instrument(self): if not isinstance(self, TestAutoInstrumentation): @@ -358,7 +411,71 @@ def test_fastapi_metrics(self): ) self.assertTrue(len(scope_metric.metrics) == 3) for metric in scope_metric.metrics: - self.assertIn(metric.name, _expected_metric_names) + self.assertIn(metric.name, _expected_metric_names_old) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs_old[metric.name] + ) + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + + def test_fastapi_metrics_new_semconv(self): + self._client.get("/foobar") + self._client.get("/foobar") + self._client.get("/foobar") + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histogram_data_point_seen = False + self.assertTrue(len(metrics_list.resource_metrics) == 1) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) == 1) + for scope_metric in resource_metric.scope_metrics: + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.fastapi", + ) + self.assertTrue(len(scope_metric.metrics) == 3) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names_new) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs_new[metric.name] + ) + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + + def test_fastapi_metrics_both_semconv(self): + self._client.get("/foobar") + self._client.get("/foobar") + self._client.get("/foobar") + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histogram_data_point_seen = False + self.assertTrue(len(metrics_list.resource_metrics) == 1) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) == 1) + for scope_metric in resource_metric.scope_metrics: + self.assertEqual( + scope_metric.scope.name, + "opentelemetry.instrumentation.fastapi", + ) + self.assertTrue(len(scope_metric.metrics) == 5) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names_both) data_points = list(metric.data.data_points) self.assertEqual(len(data_points), 1) for point in data_points: @@ -369,7 +486,7 @@ def test_fastapi_metrics(self): number_data_point_seen = True for attr in point.attributes: self.assertIn( - attr, _recommended_attrs[metric.name] + attr, _recommended_attrs_both[metric.name] ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) @@ -378,21 +495,216 @@ def test_basic_metric_success(self): self._client.get("/foobar") duration = max(round((default_timer() - start) * 1000), 0) expected_duration_attributes = { - "http.method": "GET", - "http.host": "testserver:443", - "http.scheme": "https", - "http.flavor": "1.1", - "http.server_name": "testserver", - "net.host.port": 443, - "http.status_code": 200, - "http.target": "/foobar", + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + SpanAttributes.NET_HOST_PORT: 443, + SpanAttributes.HTTP_STATUS_CODE: 200, + SpanAttributes.HTTP_TARGET: "/foobar", + } + expected_requests_count_attributes = { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) + self.assertEqual(point.count, 1) + self.assertAlmostEqual(duration, point.sum, delta=40) + if isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_metric_success_new_semconv(self): + start = default_timer() + self._client.get("/foobar") + duration_s = max(default_timer() - start, 0) + expected_duration_attributes = { + HTTP_REQUEST_METHOD: "GET", + URL_SCHEME: "https", + NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 200, + HTTP_ROUTE: "/foobar", + } + expected_requests_count_attributes = { + HTTP_REQUEST_METHOD: "GET", + URL_SCHEME: "https", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) + self.assertEqual(point.count, 1) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual(duration_s, point.sum, places=1) + elif metric.name == "http.server.response.body.size": + self.assertEqual(25, point.sum) + elif metric.name == "http.server.request.body.size": + self.assertEqual(25, point.sum) + if isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_metric_success_both_semconv(self): + start = default_timer() + self._client.get("/foobar") + duration = max(round((default_timer() - start) * 1000), 0) + duration_s = max(default_timer() - start, 0) + expected_duration_attributes_old = { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + SpanAttributes.NET_HOST_PORT: 443, + SpanAttributes.HTTP_STATUS_CODE: 200, + SpanAttributes.HTTP_TARGET: "/foobar", + } + expected_duration_attributes_new = { + HTTP_REQUEST_METHOD: "GET", + URL_SCHEME: "https", + NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 200, + HTTP_ROUTE: "/foobar", + } + expected_requests_count_attributes = { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + HTTP_REQUEST_METHOD: "GET", + URL_SCHEME: "https", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + self.assertAlmostEqual(duration, point.sum, delta=40) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.response.body.size": + self.assertEqual(25, point.sum) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.request.body.size": + self.assertEqual(25, point.sum) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.duration": + self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif metric.name == "http.server.response.size": + self.assertEqual(25, point.sum) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif metric.name == "http.server.request.size": + self.assertEqual(25, point.sum) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + if isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_metric_nonstandard_http_method_success(self): + start = default_timer() + self._client.request("NONSTANDARD", "/foobar") + duration = max(round((default_timer() - start) * 1000), 0) + expected_duration_attributes = { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + SpanAttributes.NET_HOST_PORT: 443, + SpanAttributes.HTTP_STATUS_CODE: 405, + SpanAttributes.HTTP_TARGET: "/foobar", + } + expected_requests_count_attributes = { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) + self.assertEqual(point.count, 1) + self.assertAlmostEqual(duration, point.sum, delta=40) + if isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_metric_nonstandard_http_method_success_new_semconv(self): + start = default_timer() + self._client.request("NONSTANDARD", "/foobar") + duration_s = max(default_timer() - start, 0) + expected_duration_attributes = { + HTTP_REQUEST_METHOD: "_OTHER", + URL_SCHEME: "https", + NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 405, + HTTP_ROUTE: "/foobar", } expected_requests_count_attributes = { - "http.method": "GET", - "http.host": "testserver:443", - "http.scheme": "https", - "http.flavor": "1.1", - "http.server_name": "testserver", + HTTP_REQUEST_METHOD: "_OTHER", + URL_SCHEME: "https", } metrics_list = self.memory_metrics_reader.get_metrics_data() for metric in ( @@ -404,8 +716,95 @@ def test_basic_metric_success(self): expected_duration_attributes, dict(point.attributes), ) + self.assertEqual(point.count, 1) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual(duration_s, point.sum, places=1) + elif metric.name == "http.server.response.body.size": + self.assertEqual(31, point.sum) + elif metric.name == "http.server.request.body.size": + self.assertEqual(25, point.sum) + if isinstance(point, NumberDataPoint): + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_metric_nonstandard_http_method_success_both_semconv(self): + start = default_timer() + self._client.request("NONSTANDARD", "/foobar") + duration = max(round((default_timer() - start) * 1000), 0) + duration_s = max(default_timer() - start, 0) + expected_duration_attributes_old = { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + SpanAttributes.NET_HOST_PORT: 443, + SpanAttributes.HTTP_STATUS_CODE: 405, + SpanAttributes.HTTP_TARGET: "/foobar", + } + expected_duration_attributes_new = { + HTTP_REQUEST_METHOD: "_OTHER", + URL_SCHEME: "https", + NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 405, + HTTP_ROUTE: "/foobar", + } + expected_requests_count_attributes = { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_HOST: "testserver:443", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SERVER_NAME: "testserver", + HTTP_REQUEST_METHOD: "_OTHER", + URL_SCHEME: "https", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) self.assertAlmostEqual(duration, point.sum, delta=40) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.response.body.size": + self.assertEqual(31, point.sum) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.request.body.size": + self.assertEqual(25, point.sum) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) + elif metric.name == "http.server.duration": + self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif metric.name == "http.server.response.size": + self.assertEqual(31, point.sum) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) + elif metric.name == "http.server.request.size": + self.assertEqual(25, point.sum) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) if isinstance(point, NumberDataPoint): self.assertDictEqual( expected_requests_count_attributes, @@ -438,6 +837,63 @@ def test_basic_post_request_metric_success(self): if isinstance(point, NumberDataPoint): self.assertEqual(point.value, 0) + def test_basic_post_request_metric_success_new_semconv(self): + start = default_timer() + response = self._client.post( + "/foobar", + json={"foo": "bar"}, + ) + duration_s = max(default_timer() - start, 0) + response_size = int(response.headers.get("content-length")) + request_size = int(response.request.headers.get("content-length")) + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual(duration_s, point.sum, places=1) + elif metric.name == "http.server.response.body.size": + self.assertEqual(response_size, point.sum) + elif metric.name == "http.server.request.body.size": + self.assertEqual(request_size, point.sum) + if isinstance(point, NumberDataPoint): + self.assertEqual(point.value, 0) + + def test_basic_post_request_metric_success_both_semconv(self): + start = default_timer() + response = self._client.post( + "/foobar", + json={"foo": "bar"}, + ) + duration = max(round((default_timer() - start) * 1000), 0) + duration_s = max(default_timer() - start, 0) + response_size = int(response.headers.get("content-length")) + request_size = int(response.request.headers.get("content-length")) + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + if metric.name == "http.server.request.duration": + self.assertAlmostEqual(duration_s, point.sum, places=1) + elif metric.name == "http.server.response.body.size": + self.assertEqual(response_size, point.sum) + elif metric.name == "http.server.request.body.size": + self.assertEqual(request_size, point.sum) + elif metric.name == "http.server.duration": + self.assertAlmostEqual(duration, point.sum, delta=40) + elif metric.name == "http.server.response.size": + self.assertEqual(response_size, point.sum) + elif metric.name == "http.server.request.size": + self.assertEqual(request_size, point.sum) + if isinstance(point, NumberDataPoint): + self.assertEqual(point.value, 0) + def test_metric_uninstrument_app(self): self._client.get("/foobar") self._instrumentor.uninstrument_app(self._app) 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 34e9b5ea50..eaf6c79506 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -543,7 +543,9 @@ def __init__(self, *args, **kwargs): __name__, __version__, _InstrumentedFlask._meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url( + _InstrumentedFlask._sem_conv_opt_in_mode + ), ) duration_histogram_old = None if _report_old(_InstrumentedFlask._sem_conv_opt_in_mode): @@ -579,7 +581,9 @@ def __init__(self, *args, **kwargs): __name__, __version__, _InstrumentedFlask._tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url( + _InstrumentedFlask._sem_conv_opt_in_mode + ), ) _before_request = _wrapped_before_request( From 15f3b97d5a49a3c616e3691af2b31d3f0013bb65 Mon Sep 17 00:00:00 2001 From: Gustavo Carvalho <99373133+gustavosett@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:44:44 -0300 Subject: [PATCH 094/335] Improved Test Coverage for HTTP Utility's IP Setting Functionality (#2693) --- .../tests/test_try_set_ip.py | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 util/opentelemetry-util-http/tests/test_try_set_ip.py diff --git a/util/opentelemetry-util-http/tests/test_try_set_ip.py b/util/opentelemetry-util-http/tests/test_try_set_ip.py new file mode 100644 index 0000000000..c87bf990a6 --- /dev/null +++ b/util/opentelemetry-util-http/tests/test_try_set_ip.py @@ -0,0 +1,67 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import socket +import unittest +from http.client import HTTPConnection +from unittest.mock import MagicMock, patch + +from opentelemetry.util.http.httplib import trysetip + + +class TestTrySetIP(unittest.TestCase): + def setUp(self): + # Setup a mock HTTPConnection + self.conn = MagicMock(spec=HTTPConnection) + self.conn.sock = MagicMock(spec=socket.socket) + + # Mock state function and Span class + self.mock_state = {"need_ip": [MagicMock()]} + self.mock_getstate = patch( + "opentelemetry.util.http.httplib._getstate", + return_value=self.mock_state, + ) + self.mock_getstate.start() + + def test_ip_set_successfully(self): + self.conn.sock.getpeername.return_value = ("192.168.1.1", 8080) + + success = trysetip(self.conn, loglevel=logging.DEBUG) + + # Verify that the IP was set correctly + for span in self.mock_state["need_ip"]: + span.set_attribute.assert_called_once_with( + "net.peer.ip", "192.168.1.1" + ) + self.assertTrue(success) + + def test_no_socket_connection(self): + # Setup the connection with no socket + self.conn.sock = None + + success = trysetip(self.conn, loglevel=logging.DEBUG) + + self.assertFalse(success) + + def test_exception_during_ip_retrieval(self): + self.conn.sock.getpeername.side_effect = Exception("Test Exception") + + with self.assertLogs(level=logging.WARNING) as warning: + success = trysetip(self.conn, loglevel=logging.WARNING) + self.assertEqual(len(warning.records), 1) + self.assertIn( + "Failed to get peer address", warning.records[0].message + ) + self.assertTrue(success) From 6bc48be45af45769ed071b14d684d1d40b3d155e Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Sat, 13 Jul 2024 01:34:34 +0200 Subject: [PATCH 095/335] exporter/prometheus-remote-write: bump certifi to latest (#2701) Co-authored-by: Leighton Chen --- .../test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index ec8f90336d..f7e66ddd13 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -1,5 +1,5 @@ asgiref==3.7.2 -certifi==2024.2.2 +certifi==2024.7.4 charset-normalizer==3.3.2 # We can drop this after bumping baseline to pypy-39 cramjam==2.1.0; platform_python_implementation == "PyPy" From 432d6f570cbe28599a00cef5e369da0f860ffd7f Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 15 Jul 2024 18:54:14 +0200 Subject: [PATCH 096/335] instrumentation/django: bump django 4.2 to 4.2.14 (#2700) --- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 9c78f42e46..2ed199fbf3 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,7 +1,7 @@ asgiref==3.7.2 backports.zoneinfo==0.2.1 Deprecated==1.2.14 -Django==4.2.11 +Django==4.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index 77c049d87b..c3e65be730 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -1,6 +1,6 @@ asgiref==3.7.2 Deprecated==1.2.14 -Django==4.2.11 +Django==4.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 From 7567efa341450a73c06580c0e12b53dec9ca0b10 Mon Sep 17 00:00:00 2001 From: Zhihan Li <54661071+zhihali@users.noreply.github.com> Date: Mon, 15 Jul 2024 18:09:36 +0100 Subject: [PATCH 097/335] Handle redis.exceptions.WatchError as a non-error event in instrumentation (#2668) --- CHANGELOG.md | 3 +- .../instrumentation/redis/__init__.py | 19 ++- .../test-requirements.txt | 1 + .../tests/test_redis.py | 117 +++++++++++++++++- 4 files changed, 135 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6882cbe57..7bf02de0e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) ### Fixed - +- Handle `redis.exceptions.WatchError` as a non-error event in redis instrumentation + ([#2668](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2668)) - `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented ([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538)) - Add Python 3.12 support diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index 1d61e8cfd3..c5f19fc736 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -106,7 +106,7 @@ def response_hook(span, instance, response): from opentelemetry.instrumentation.redis.version import __version__ from opentelemetry.instrumentation.utils import unwrap from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import Span +from opentelemetry.trace import Span, StatusCode _DEFAULT_SERVICE = "redis" @@ -212,9 +212,16 @@ def _traced_execute_pipeline(func, instance, args, kwargs): span.set_attribute( "db.redis.pipeline_length", len(command_stack) ) - response = func(*args, **kwargs) + + response = None + try: + response = func(*args, **kwargs) + except redis.WatchError: + span.set_status(StatusCode.UNSET) + if callable(response_hook): response_hook(span, instance, response) + return response pipeline_class = ( @@ -281,7 +288,13 @@ async def _async_traced_execute_pipeline(func, instance, args, kwargs): span.set_attribute( "db.redis.pipeline_length", len(command_stack) ) - response = await func(*args, **kwargs) + + response = None + try: + response = await func(*args, **kwargs) + except redis.WatchError: + span.set_status(StatusCode.UNSET) + if callable(response_hook): response_hook(span, instance, response) return response diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 1731de082a..43d4bd9788 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -1,6 +1,7 @@ asgiref==3.7.2 async-timeout==4.0.3 Deprecated==1.2.14 +fakeredis==2.23.3 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py index 4a2fce5026..23d21b6e5a 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py +++ b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py @@ -12,11 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio -from unittest import mock +from unittest import IsolatedAsyncioTestCase, mock from unittest.mock import AsyncMock +import fakeredis +import pytest import redis import redis.asyncio +from fakeredis.aioredis import FakeRedis +from redis.exceptions import ConnectionError as redis_ConnectionError +from redis.exceptions import WatchError from opentelemetry import trace from opentelemetry.instrumentation.redis import RedisInstrumentor @@ -311,3 +316,113 @@ def test_attributes_unix_socket(self): span.attributes[SpanAttributes.NET_TRANSPORT], NetTransportValues.OTHER.value, ) + + def test_connection_error(self): + server = fakeredis.FakeServer() + server.connected = False + redis_client = fakeredis.FakeStrictRedis(server=server) + try: + redis_client.set("foo", "bar") + except redis_ConnectionError: + pass + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + span = spans[0] + + self.assertEqual(span.name, "SET") + self.assertEqual(span.kind, SpanKind.CLIENT) + self.assertEqual(span.status.status_code, trace.StatusCode.ERROR) + + def test_response_error(self): + redis_client = fakeredis.FakeStrictRedis() + redis_client.lpush("mylist", "value") + try: + redis_client.incr( + "mylist" + ) # Trying to increment a list, which is invalid + except redis.ResponseError: + pass + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + + span = spans[0] + self.assertEqual(span.name, "LPUSH") + self.assertEqual(span.kind, SpanKind.CLIENT) + self.assertEqual(span.status.status_code, trace.StatusCode.UNSET) + + span = spans[1] + self.assertEqual(span.name, "INCRBY") + self.assertEqual(span.kind, SpanKind.CLIENT) + self.assertEqual(span.status.status_code, trace.StatusCode.ERROR) + + def test_watch_error_sync(self): + def redis_operations(): + try: + redis_client = fakeredis.FakeStrictRedis() + pipe = redis_client.pipeline(transaction=True) + pipe.watch("a") + redis_client.set("a", "bad") # This will cause the WatchError + pipe.multi() + pipe.set("a", "1") + pipe.execute() + except WatchError: + pass + + redis_operations() + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 3) + + # there should be 3 tests, we start watch operation and have 2 set operation on same key + self.assertEqual(len(spans), 3) + + self.assertEqual(spans[0].attributes.get("db.statement"), "WATCH ?") + self.assertEqual(spans[0].kind, SpanKind.CLIENT) + self.assertEqual(spans[0].status.status_code, trace.StatusCode.UNSET) + + for span in spans[1:]: + self.assertEqual(span.attributes.get("db.statement"), "SET ? ?") + self.assertEqual(span.kind, SpanKind.CLIENT) + self.assertEqual(span.status.status_code, trace.StatusCode.UNSET) + + +class TestRedisAsync(TestBase, IsolatedAsyncioTestCase): + def setUp(self): + super().setUp() + RedisInstrumentor().instrument(tracer_provider=self.tracer_provider) + + def tearDown(self): + super().tearDown() + RedisInstrumentor().uninstrument() + + @pytest.mark.asyncio + async def test_watch_error_async(self): + async def redis_operations(): + try: + redis_client = FakeRedis() + async with redis_client.pipeline(transaction=False) as pipe: + await pipe.watch("a") + await redis_client.set("a", "bad") + pipe.multi() + await pipe.set("a", "1") + await pipe.execute() + except WatchError: + pass + + await redis_operations() + + spans = self.memory_exporter.get_finished_spans() + + # there should be 3 tests, we start watch operation and have 2 set operation on same key + self.assertEqual(len(spans), 3) + + self.assertEqual(spans[0].attributes.get("db.statement"), "WATCH ?") + self.assertEqual(spans[0].kind, SpanKind.CLIENT) + self.assertEqual(spans[0].status.status_code, trace.StatusCode.UNSET) + + for span in spans[1:]: + self.assertEqual(span.attributes.get("db.statement"), "SET ? ?") + self.assertEqual(span.kind, SpanKind.CLIENT) + self.assertEqual(span.status.status_code, trace.StatusCode.UNSET) From 7c7a2a4312060e4ff55a718a8efb289b16b10803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Sm=C4=99t?= <1754812+artursmet@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:24:16 +0200 Subject: [PATCH 098/335] Add documentation for request/response hooks for requests instrumentor (#2704) --- .../instrumentation/requests/__init__.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 18cc3e767c..0a55564386 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -31,6 +31,30 @@ Configuration ------------- +Request/Response hooks +********************** + +The requests instrumentation supports extending tracing behavior with the help of +request and response hooks. These are functions that are called back by the instrumentation +right after a Span is created for a request and right before the span is finished processing a response respectively. +The hooks can be configured as follows: + +.. code:: python + + # `request_obj` is an instance of requests.PreparedRequest + def request_hook(span, request_obj): + pass + + # `request_obj` is an instance of requests.PreparedRequest + # `response` is an instance of requests.Response + def response_hook(span, request_obj, response) + pass + + RequestsInstrumentor().instrument( + request_hook=request_hook, response_hook=response_hook) + ) + + Exclude lists ************* To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_REQUESTS_EXCLUDED_URLS`` From 7e48ee7254067f68af547e44cdffa7699c0b8778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 15 Jul 2024 17:49:35 -0300 Subject: [PATCH 099/335] HTTP semantic convention stability migration for aiohttp-client (#2673) --- CHANGELOG.md | 2 + instrumentation/README.md | 2 +- .../aiohttp_client/__init__.py | 99 +++++-- .../instrumentation/aiohttp_client/package.py | 4 + .../tests/test_aiohttp_client_integration.py | 278 ++++++++++++++++-- .../instrumentation/asgi/__init__.py | 3 +- .../instrumentation/wsgi/__init__.py | 3 +- .../opentelemetry/instrumentation/_semconv.py | 13 +- 8 files changed, 348 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bf02de0e3..f4573e4b44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) - `opentelemetry-instrumentation-system-metrics` Add support for capture open file descriptors ([#2652](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2652)) +- `opentelemetry-instrumentation-aiohttp-client` Implement new semantic convention opt-in migration + ([#2673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2673)) ### Breaking changes diff --git a/instrumentation/README.md b/instrumentation/README.md index 9add6d0228..bbc5d8d75c 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -2,7 +2,7 @@ | Instrumentation | Supported Packages | Metrics support | Semconv status | | --------------- | ------------------ | --------------- | -------------- | | [opentelemetry-instrumentation-aio-pika](./opentelemetry-instrumentation-aio-pika) | aio_pika >= 7.2.0, < 10.0.0 | No | experimental -| [opentelemetry-instrumentation-aiohttp-client](./opentelemetry-instrumentation-aiohttp-client) | aiohttp ~= 3.0 | No | experimental +| [opentelemetry-instrumentation-aiohttp-client](./opentelemetry-instrumentation-aiohttp-client) | aiohttp ~= 3.0 | No | migration | [opentelemetry-instrumentation-aiohttp-server](./opentelemetry-instrumentation-aiohttp-server) | aiohttp ~= 3.0 | No | experimental | [opentelemetry-instrumentation-aiopg](./opentelemetry-instrumentation-aiopg) | aiopg >= 0.13.0, < 2.0.0 | No | experimental | [opentelemetry-instrumentation-asgi](./opentelemetry-instrumentation-asgi) | asgiref ~= 3.0 | Yes | migration diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index 9f842bde79..459e3121b9 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -90,19 +90,28 @@ def response_hook(span: Span, params: typing.Union[ from opentelemetry import context as context_api from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + _get_schema_url, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _set_http_method, + _set_http_url, + _set_status, +) from opentelemetry.instrumentation.aiohttp_client.package import _instruments from opentelemetry.instrumentation.aiohttp_client.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.utils import ( - http_status_to_status_code, is_instrumentation_enabled, unwrap, ) from opentelemetry.propagate import inject -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.trace import Span, SpanKind, TracerProvider, get_tracer from opentelemetry.trace.status import Status, StatusCode -from opentelemetry.util.http import remove_url_credentials +from opentelemetry.util.http import remove_url_credentials, sanitize_method _UrlFilterT = typing.Optional[typing.Callable[[yarl.URL], str]] _RequestHookT = typing.Optional[ @@ -122,11 +131,46 @@ def response_hook(span: Span, params: typing.Union[ ] +def _get_span_name(method: str) -> str: + method = sanitize_method(method.upper().strip()) + if method == "_OTHER": + method = "HTTP" + + return method + + +def _set_http_status_code_attribute( + span, + status_code, + metric_attributes=None, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, +): + status_code_str = str(status_code) + try: + status_code = int(status_code) + except ValueError: + status_code = -1 + if metric_attributes is None: + metric_attributes = {} + # When we have durations we should set metrics only once + # Also the decision to include status code on a histogram should + # not be dependent on tracing decisions. + _set_status( + span, + metric_attributes, + status_code, + status_code_str, + server_span=False, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + ) + + def create_trace_config( url_filter: _UrlFilterT = None, request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, tracer_provider: TracerProvider = None, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ) -> aiohttp.TraceConfig: """Create an aiohttp-compatible trace configuration. @@ -167,9 +211,12 @@ def create_trace_config( __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) + # TODO: Use this when we have durations for aiohttp-client + metric_attributes = {} + def _end_trace(trace_config_ctx: types.SimpleNamespace): context_api.detach(trace_config_ctx.token) trace_config_ctx.span.end() @@ -183,18 +230,22 @@ async def on_request_start( trace_config_ctx.span = None return - http_method = params.method.upper() - request_span_name = f"{http_method}" + http_method = params.method + request_span_name = _get_span_name(http_method) request_url = ( remove_url_credentials(trace_config_ctx.url_filter(params.url)) if callable(trace_config_ctx.url_filter) else remove_url_credentials(str(params.url)) ) - span_attributes = { - SpanAttributes.HTTP_METHOD: http_method, - SpanAttributes.HTTP_URL: request_url, - } + span_attributes = {} + _set_http_method( + span_attributes, + http_method, + request_span_name, + sem_conv_opt_in_mode, + ) + _set_http_url(span_attributes, request_url, sem_conv_opt_in_mode) trace_config_ctx.span = trace_config_ctx.tracer.start_span( request_span_name, kind=SpanKind.CLIENT, attributes=span_attributes @@ -219,14 +270,13 @@ async def on_request_end( if callable(response_hook): response_hook(trace_config_ctx.span, params) + _set_http_status_code_attribute( + trace_config_ctx.span, + params.response.status, + metric_attributes, + sem_conv_opt_in_mode, + ) - if trace_config_ctx.span.is_recording(): - trace_config_ctx.span.set_status( - Status(http_status_to_status_code(int(params.response.status))) - ) - trace_config_ctx.span.set_attribute( - SpanAttributes.HTTP_STATUS_CODE, params.response.status - ) _end_trace(trace_config_ctx) async def on_request_exception( @@ -238,7 +288,13 @@ async def on_request_exception( return if trace_config_ctx.span.is_recording() and params.exception: - trace_config_ctx.span.set_status(Status(StatusCode.ERROR)) + exc_type = type(params.exception).__qualname__ + if _report_new(sem_conv_opt_in_mode): + trace_config_ctx.span.set_attribute(ERROR_TYPE, exc_type) + + trace_config_ctx.span.set_status( + Status(StatusCode.ERROR, exc_type) + ) trace_config_ctx.span.record_exception(params.exception) if callable(response_hook): @@ -271,6 +327,7 @@ def _instrument( trace_configs: typing.Optional[ typing.Sequence[aiohttp.TraceConfig] ] = None, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ): """Enables tracing of all ClientSessions @@ -293,6 +350,7 @@ def instrumented_init(wrapped, instance, args, kwargs): request_hook=request_hook, response_hook=response_hook, tracer_provider=tracer_provider, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, ) trace_config._is_instrumented_by_opentelemetry = True client_trace_configs.append(trace_config) @@ -344,12 +402,17 @@ def _instrument(self, **kwargs): ``trace_configs``: An optional list of aiohttp.TraceConfig items, allowing customize enrichment of spans based on aiohttp events (see specification: https://docs.aiohttp.org/en/stable/tracing_reference.html) """ + _OpenTelemetrySemanticConventionStability._initialize() + _sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) _instrument( tracer_provider=kwargs.get("tracer_provider"), url_filter=kwargs.get("url_filter"), request_hook=kwargs.get("request_hook"), response_hook=kwargs.get("response_hook"), trace_configs=kwargs.get("trace_configs"), + sem_conv_opt_in_mode=_sem_conv_opt_in_mode, ) def _uninstrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/package.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/package.py index c9b6b6fe27..98ae4b0874 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/package.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/package.py @@ -14,3 +14,7 @@ _instruments = ("aiohttp ~= 3.0",) + +_supports_metrics = False + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index b6fe1eb57a..538421dd6a 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -28,10 +28,21 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation import aiohttp_client +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.aiohttp_client import ( AioHttpClientInstrumentor, ) from opentelemetry.instrumentation.utils import suppress_instrumentation +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.url_attributes import URL_FULL from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.trace import Span, StatusCode @@ -59,7 +70,23 @@ async def do_request(): class TestAioHttpIntegration(TestBase): - def assert_spans(self, spans): + + _test_status_codes = ( + (HTTPStatus.OK, StatusCode.UNSET), + (HTTPStatus.TEMPORARY_REDIRECT, StatusCode.UNSET), + (HTTPStatus.NOT_FOUND, StatusCode.ERROR), + (HTTPStatus.BAD_REQUEST, StatusCode.ERROR), + (HTTPStatus.SERVICE_UNAVAILABLE, StatusCode.ERROR), + (HTTPStatus.GATEWAY_TIMEOUT, StatusCode.ERROR), + ) + + def setUp(self): + super().setUp() + _OpenTelemetrySemanticConventionStability._initialized = False + + def assert_spans(self, spans, num_spans=1): + finished_spans = self.memory_exporter.get_finished_spans() + self.assertEqual(num_spans, len(finished_spans)) self.assertEqual( [ ( @@ -67,7 +94,7 @@ def assert_spans(self, spans): (span.status.status_code, span.status.description), dict(span.attributes), ) - for span in self.memory_exporter.get_finished_spans() + for span in finished_spans ], spans, ) @@ -99,39 +126,72 @@ async def client_request(server: aiohttp.test_utils.TestServer): return run_with_test_server(client_request, url, handler) def test_status_codes(self): - for status_code, span_status in ( - (HTTPStatus.OK, StatusCode.UNSET), - (HTTPStatus.TEMPORARY_REDIRECT, StatusCode.UNSET), - (HTTPStatus.SERVICE_UNAVAILABLE, StatusCode.ERROR), - ( - HTTPStatus.GATEWAY_TIMEOUT, - StatusCode.ERROR, - ), - ): + for status_code, span_status in self._test_status_codes: with self.subTest(status_code=status_code): + path = "test-path?query=param#foobar" host, port = self._http_request( trace_config=aiohttp_client.create_trace_config(), - url="/test-path?query=param#foobar", + url=f"/{path}", status_code=status_code, ) + url = f"http://{host}:{port}/{path}" + attributes = { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_URL: url, + SpanAttributes.HTTP_STATUS_CODE: status_code, + } + spans = [("GET", (span_status, None), attributes)] + self.assert_spans(spans) + self.memory_exporter.clear() - url = f"http://{host}:{port}/test-path?query=param#foobar" - self.assert_spans( - [ - ( - "GET", - (span_status, None), - { - SpanAttributes.HTTP_METHOD: "GET", - SpanAttributes.HTTP_URL: url, - SpanAttributes.HTTP_STATUS_CODE: int( - status_code - ), - }, - ) - ] + def test_status_codes_new_semconv(self): + for status_code, span_status in self._test_status_codes: + with self.subTest(status_code=status_code): + path = "test-path?query=param#foobar" + host, port = self._http_request( + trace_config=aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + ), + url=f"/{path}", + status_code=status_code, ) + url = f"http://{host}:{port}/{path}" + attributes = { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url, + HTTP_RESPONSE_STATUS_CODE: status_code, + } + if status_code >= 400: + attributes[ERROR_TYPE] = str(status_code.value) + spans = [("GET", (span_status, None), attributes)] + self.assert_spans(spans) + self.memory_exporter.clear() + def test_status_codes_both_semconv(self): + for status_code, span_status in self._test_status_codes: + with self.subTest(status_code=status_code): + path = "test-path?query=param#foobar" + host, port = self._http_request( + trace_config=aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + ), + url=f"/{path}", + status_code=status_code, + ) + url = f"http://{host}:{port}/{path}" + attributes = { + HTTP_REQUEST_METHOD: "GET", + SpanAttributes.HTTP_METHOD: "GET", + URL_FULL: url, + SpanAttributes.HTTP_URL: url, + HTTP_RESPONSE_STATUS_CODE: status_code, + SpanAttributes.HTTP_STATUS_CODE: status_code, + } + if status_code >= 400: + attributes[ERROR_TYPE] = str(status_code.value) + + spans = [("GET", (span_status, None), attributes)] + self.assert_spans(spans, 1) self.memory_exporter.clear() def test_schema_url(self): @@ -149,6 +209,40 @@ def test_schema_url(self): ) self.memory_exporter.clear() + def test_schema_url_new_semconv(self): + with self.subTest(status_code=200): + self._http_request( + trace_config=aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + ), + url="/test-path?query=param#foobar", + status_code=200, + ) + + span = self.memory_exporter.get_finished_spans()[0] + self.assertEqual( + span.instrumentation_info.schema_url, + "https://opentelemetry.io/schemas/v1.21.0", + ) + self.memory_exporter.clear() + + def test_schema_url_both_semconv(self): + with self.subTest(status_code=200): + self._http_request( + trace_config=aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + ), + url="/test-path?query=param#foobar", + status_code=200, + ) + + span = self.memory_exporter.get_finished_spans()[0] + self.assertEqual( + span.instrumentation_info.schema_url, + "https://opentelemetry.io/schemas/v1.21.0", + ) + self.memory_exporter.clear() + def test_not_recording(self): mock_tracer = mock.Mock() mock_span = mock.Mock() @@ -263,7 +357,7 @@ async def do_request(url): [ ( "GET", - (expected_status, None), + (expected_status, "ClientConnectorError"), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: url, @@ -273,6 +367,89 @@ async def do_request(url): ) self.memory_exporter.clear() + def test_basic_exception(self): + async def request_handler(request): + assert "traceparent" in request.headers + + host, port = self._http_request( + trace_config=aiohttp_client.create_trace_config(), + url="/test", + request_handler=request_handler, + ) + span = self.memory_exporter.get_finished_spans()[0] + self.assertEqual(len(span.events), 1) + self.assertEqual(span.events[0].name, "exception") + self.assert_spans( + [ + ( + "GET", + (StatusCode.ERROR, "ServerDisconnectedError"), + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_URL: f"http://{host}:{port}/test", + }, + ) + ] + ) + + def test_basic_exception_new_semconv(self): + async def request_handler(request): + assert "traceparent" in request.headers + + host, port = self._http_request( + trace_config=aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + ), + url="/test", + request_handler=request_handler, + ) + span = self.memory_exporter.get_finished_spans()[0] + self.assertEqual(len(span.events), 1) + self.assertEqual(span.events[0].name, "exception") + self.assert_spans( + [ + ( + "GET", + (StatusCode.ERROR, "ServerDisconnectedError"), + { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: f"http://{host}:{port}/test", + ERROR_TYPE: "ServerDisconnectedError", + }, + ) + ] + ) + + def test_basic_exception_both_semconv(self): + async def request_handler(request): + assert "traceparent" in request.headers + + host, port = self._http_request( + trace_config=aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + ), + url="/test", + request_handler=request_handler, + ) + span = self.memory_exporter.get_finished_spans()[0] + self.assertEqual(len(span.events), 1) + self.assertEqual(span.events[0].name, "exception") + self.assert_spans( + [ + ( + "GET", + (StatusCode.ERROR, "ServerDisconnectedError"), + { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: f"http://{host}:{port}/test", + ERROR_TYPE: "ServerDisconnectedError", + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_URL: f"http://{host}:{port}/test", + }, + ) + ] + ) + def test_timeout(self): async def request_handler(request): await asyncio.sleep(1) @@ -290,7 +467,7 @@ async def request_handler(request): [ ( "GET", - (StatusCode.ERROR, None), + (StatusCode.ERROR, "ServerTimeoutError"), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: f"http://{host}:{port}/test_timeout", @@ -317,7 +494,7 @@ async def request_handler(request): [ ( "GET", - (StatusCode.ERROR, None), + (StatusCode.ERROR, "TooManyRedirects"), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: f"http://{host}:{port}/test_too_many_redirects", @@ -374,6 +551,7 @@ class TestAioHttpClientInstrumentor(TestBase): def setUp(self): super().setUp() AioHttpClientInstrumentor().instrument() + _OpenTelemetrySemanticConventionStability._initialized = False def tearDown(self): super().tearDown() @@ -414,6 +592,46 @@ def test_instrument(self): ) self.assertEqual(200, span.attributes[SpanAttributes.HTTP_STATUS_CODE]) + def test_instrument_new_semconv(self): + AioHttpClientInstrumentor().uninstrument() + with mock.patch.dict( + "os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "http"} + ): + AioHttpClientInstrumentor().instrument() + host, port = run_with_test_server( + self.get_default_request(), self.URL, self.default_handler + ) + span = self.assert_spans(1) + self.assertEqual("GET", span.name) + self.assertEqual("GET", span.attributes[HTTP_REQUEST_METHOD]) + self.assertEqual( + f"http://{host}:{port}/test-path", + span.attributes[URL_FULL], + ) + self.assertEqual(200, span.attributes[HTTP_RESPONSE_STATUS_CODE]) + + def test_instrument_both_semconv(self): + AioHttpClientInstrumentor().uninstrument() + with mock.patch.dict( + "os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "http/dup"} + ): + AioHttpClientInstrumentor().instrument() + host, port = run_with_test_server( + self.get_default_request(), self.URL, self.default_handler + ) + url = f"http://{host}:{port}/test-path" + attributes = { + HTTP_REQUEST_METHOD: "GET", + SpanAttributes.HTTP_METHOD: "GET", + URL_FULL: url, + SpanAttributes.HTTP_URL: url, + HTTP_RESPONSE_STATUS_CODE: 200, + SpanAttributes.HTTP_STATUS_CODE: 200, + } + span = self.assert_spans(1) + self.assertEqual("GET", span.name) + self.assertEqual(span.attributes, attributes) + def test_instrument_with_custom_trace_config(self): trace_config = aiohttp.TraceConfig() diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 7e51837d4d..0525181eac 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -451,7 +451,8 @@ def set_status_code( metric_attributes, status_code, status_code_str, - sem_conv_opt_in_mode, + server_span=True, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, ) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index d75147d6aa..355b1d7458 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -496,7 +496,8 @@ def add_response_attributes( duration_attrs, status_code, status_code_str, - sem_conv_opt_in_mode, + server_span=True, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 7e81692a98..33668333ce 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -349,10 +349,11 @@ def _set_http_flavor_version(result, version, sem_conv_opt_in_mode): def _set_status( span, - metrics_attributes, - status_code, - status_code_str, - sem_conv_opt_in_mode, + metrics_attributes: dict, + status_code: int, + status_code_str: str, + server_span: bool = True, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ): if status_code < 0: metrics_attributes[ERROR_TYPE] = status_code_str @@ -366,7 +367,9 @@ def _set_status( ) ) else: - status = http_status_to_status_code(status_code, server_span=True) + status = http_status_to_status_code( + status_code, server_span=server_span + ) if _report_old(sem_conv_opt_in_mode): if span.is_recording(): From f8f58ee411ac2e318512717378cd365ba4aa7a66 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Tue, 16 Jul 2024 20:06:59 +0200 Subject: [PATCH 100/335] Add `http.target` to Django duration metric attributes (#2624) --- CHANGELOG.md | 2 ++ .../instrumentation/django/middleware/otel_middleware.py | 6 ++++++ .../tests/test_middleware.py | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4573e4b44..57447ccf97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2652](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2652)) - `opentelemetry-instrumentation-aiohttp-client` Implement new semantic convention opt-in migration ([#2673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2673)) +- `opentelemetry-instrumentation-django` Add `http.target` to Django duration metric attributes + ([#2624](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2624)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 6b64865ef7..11e92c9757 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -315,6 +315,12 @@ def process_view(self, request, view_func, *args, **kwargs): route = getattr(match, "route", None) if route: span.set_attribute(SpanAttributes.HTTP_ROUTE, route) + duration_attrs = request.META[ + self._environ_duration_attr_key + ] + # Metrics currently use the 1.11.0 schema, which puts the route in `http.target`. + # TODO: use `http.route` when the user sets `OTEL_SEMCONV_STABILITY_OPT_IN`. + duration_attrs[SpanAttributes.HTTP_TARGET] = route def process_exception(self, request, exception): if self._excluded_urls.url_disabled(request.build_absolute_uri("?")): diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index c6b0568ef8..4945f05455 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -480,7 +480,8 @@ def test_wsgi_metrics(self): ] _recommended_attrs = { "http.server.active_requests": _active_requests_count_attrs, - "http.server.duration": _duration_attrs, + "http.server.duration": _duration_attrs + | {SpanAttributes.HTTP_TARGET}, } start = default_timer() for _ in range(3): From 24bc71eb2ef1a66a6563be3155000d91cdd48501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:57:38 -0300 Subject: [PATCH 101/335] Remove package install from aiopg instrumentation (#2712) Co-authored-by: Diego Hurtado --- .../opentelemetry-instrumentation-aiopg/test-requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 8a465a3326..bc61c3d6fc 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -4,7 +4,6 @@ async-timeout==4.0.3 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 -install==1.3.5 packaging==24.0 pluggy==1.5.0 psycopg2-binary==2.9.9 From 5a7935ff1fa66cee2bffd850b1f4062667fa3391 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Jul 2024 14:20:02 -0600 Subject: [PATCH 102/335] Deprecate sklearn instrumentation (#2708) Fixes #2176 --- .github/workflows/instrumentations_0.yml | 11 - .github/workflows/lint.yml | 28 - CHANGELOG.md | 2 + eachdist.ini | 1 - instrumentation/README.md | 1 - .../LICENSE | 201 ----- .../README.rst | 24 - .../pyproject.toml | 49 -- .../instrumentation/sklearn/__init__.py | 792 ------------------ .../instrumentation/sklearn/package.py | 16 - .../instrumentation/sklearn/version.py | 15 - .../test-requirements.txt | 19 - .../tests/__init__.py | 0 .../tests/fixtures.py | 54 -- .../tests/test_sklearn.py | 190 ----- .../pyproject.toml | 1 - .../instrumentation/bootstrap_gen.py | 4 - tox.ini | 16 - 18 files changed, 2 insertions(+), 1422 deletions(-) delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/LICENSE delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/README.rst delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/__init__.py delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/package.py delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/tests/__init__.py delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/tests/fixtures.py delete mode 100644 instrumentation/opentelemetry-instrumentation-sklearn/tests/test_sklearn.py diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index d54cb50119..69c07bfacc 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -66,7 +66,6 @@ jobs: - "redis" - "remoulade" - "requests" - - "sklearn" - "sqlalchemy" - "sqlite3" - "starlette" @@ -75,14 +74,6 @@ jobs: - "tortoiseorm" os: [ubuntu-20.04] exclude: - - python-version: py39 - package: "sklearn" - - python-version: py310 - package: "sklearn" - - python-version: py311 - package: "sklearn" - - python-version: py312 - package: "sklearn" - python-version: py312 package: "boto" - python-version: py312 @@ -103,8 +94,6 @@ jobs: package: "remoulade" - python-version: pypy3 package: "requests" - - python-version: pypy3 - package: "sklearn" - python-version: pypy3 package: "confluent-kafka" - python-version: pypy3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c156f7d942..29cd5cac16 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -93,31 +93,3 @@ jobs: key: v7-build-tox-cache-${{ matrix.package }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - name: run tox run: tox -e lint-${{ matrix.package }} - - lint-3_8: - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - package: - - "instrumentation-sklearn" - os: [ubuntu-20.04] - runs-on: ubuntu-20.04 - steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: 3.8 - - name: Install tox - run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v7-build-tox-cache-${{ matrix.package }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run tox - run: tox -e lint-${{ matrix.package }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 57447ccf97..2de76b2736 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-sklearn` Deprecated the sklearn instrumentation + ([#2708](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2708)) - `opentelemetry-instrumentation-pyramid` Record exceptions raised when serving a request ([#2622](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2622)) - `opentelemetry-sdk-extension-aws` Add AwsXrayLambdaPropagator diff --git a/eachdist.ini b/eachdist.ini index 7f170e4947..b698eaf299 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -54,7 +54,6 @@ packages= [lintroots] extraroots=examples/*,scripts/ subglob=*.py,tests/,test/,src/*,examples/* -ignore=sklearn [testroots] extraroots=examples/*,tests/ diff --git a/instrumentation/README.md b/instrumentation/README.md index bbc5d8d75c..989ba529cb 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -38,7 +38,6 @@ | [opentelemetry-instrumentation-redis](./opentelemetry-instrumentation-redis) | redis >= 2.6 | No | experimental | [opentelemetry-instrumentation-remoulade](./opentelemetry-instrumentation-remoulade) | remoulade >= 0.50 | No | experimental | [opentelemetry-instrumentation-requests](./opentelemetry-instrumentation-requests) | requests ~= 2.0 | Yes | migration -| [opentelemetry-instrumentation-sklearn](./opentelemetry-instrumentation-sklearn) | scikit-learn ~= 0.24.0 | No | experimental | [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy | Yes | experimental | [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | experimental | [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette ~= 0.13.0 | Yes | experimental diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/LICENSE b/instrumentation/opentelemetry-instrumentation-sklearn/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/README.rst b/instrumentation/opentelemetry-instrumentation-sklearn/README.rst deleted file mode 100644 index 9a3300c4f2..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/README.rst +++ /dev/null @@ -1,24 +0,0 @@ -OpenTelemetry Scikit-Learn Instrumentation -========================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-sklearn.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-sklearn/ - -This library allows tracing HTTP requests made by the -`scikit-learn `_ library. - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation-sklearn - -References ----------- - -* `OpenTelemetry sklearn Instrumentation `_ -* `OpenTelemetry Project `_ -* `OpenTelemetry Python Examples `_ diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml deleted file mode 100644 index 6e57529ed1..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/pyproject.toml +++ /dev/null @@ -1,49 +0,0 @@ -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project] -name = "opentelemetry-instrumentation-sklearn" -dynamic = ["version"] -description = "OpenTelemetry sklearn instrumentation" -readme = "README.rst" -license = "Apache-2.0" -requires-python = ">=3.8" -authors = [ - { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, -] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", -] -dependencies = [ - "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", -] - -[project.optional-dependencies] -instruments = [ - "scikit-learn ~= 0.24.0", -] - -[project.entry-points.opentelemetry_instrumentor] -sklearn = "opentelemetry.instrumentation.sklearn:SklearnInstrumentor" - -[project.urls] -Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-sklearn" - -[tool.hatch.version] -path = "src/opentelemetry/instrumentation/sklearn/version.py" - -[tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", -] - -[tool.hatch.build.targets.wheel] -packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/__init__.py b/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/__init__.py deleted file mode 100644 index a67bfa6ef4..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/__init__.py +++ /dev/null @@ -1,792 +0,0 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -The integration with sklearn supports the scikit-learn compatible libraries, -it can be enabled by using ``SklearnInstrumentor``. - -.. sklearn: https://github.com/scikit-learn/scikit-learn - -Usage ------ - -Package instrumentation example: - -.. code-block:: python - - from opentelemetry.instrumentation.sklearn import SklearnInstrumentor - - # instrument the sklearn library - SklearnInstrumentor().instrument() - - # instrument sklearn and other libraries - SklearnInstrumentor( - packages=["sklearn", "lightgbm", "xgboost"] - ).instrument() - - -Model instrumentation example: - -.. code-block:: python - - from opentelemetry.instrumentation.sklearn import SklearnInstrumentor - from sklearn.datasets import load_iris - from sklearn.ensemble import RandomForestClassifier - from sklearn.model_selection import train_test_split - from sklearn.pipeline import Pipeline - - X, y = load_iris(return_X_y=True) - X_train, X_test, y_train, y_test = train_test_split(X, y) - - model = Pipeline( - [ - ("class", RandomForestClassifier(n_estimators=10)), - ] - ) - - model.fit(X_train, y_train) - - SklearnInstrumentor().instrument_estimator(model) - -""" -import logging -import os -from functools import wraps -from importlib import import_module -from inspect import isclass -from pkgutil import iter_modules -from typing import ( - Callable, - Collection, - Dict, - List, - MutableMapping, - Sequence, - Type, - Union, -) - -from sklearn.base import BaseEstimator -from sklearn.pipeline import FeatureUnion, Pipeline -from sklearn.tree import BaseDecisionTree -from sklearn.utils.metaestimators import _IffHasAttrDescriptor - -from opentelemetry.instrumentation.instrumentor import BaseInstrumentor - -# pylint: disable=no-name-in-module -from opentelemetry.instrumentation.sklearn.package import _instruments -from opentelemetry.instrumentation.sklearn.version import __version__ -from opentelemetry.trace import get_tracer -from opentelemetry.util.types import Attributes - -logger = logging.getLogger(__name__) - - -def implement_span_estimator( - func: Callable, - estimator: Union[BaseEstimator, Type[BaseEstimator]], - attributes: Attributes = None, -): - """Wrap the method call with a span. - - Args: - func: A callable to be wrapped in a span - estimator: An instance or class of an estimator - attributes: Attributes to apply to the span - - Returns: - The passed function wrapped in a span. - """ - if isclass(estimator): - name = estimator.__name__ - else: - name = estimator.__class__.__name__ - logger.debug("Instrumenting: %s.%s", name, func.__name__) - attributes = attributes or {} - name = f"{name}.{func.__name__}" - return implement_span_function(func, name, attributes) - - -def implement_span_function(func: Callable, name: str, attributes: Attributes): - """Wrap the function with a span. - - Args: - func: A callable to be wrapped in a span - name: The name of the span - attributes: Attributes to apply to the span - - Returns: - The passed function wrapped in a span. - """ - - @wraps(func) - def wrapper(*args, **kwargs): - with get_tracer( - __name__, - __version__, - schema_url="https://opentelemetry.io/schemas/1.11.0", - ).start_as_current_span(name=name) as span: - if span.is_recording(): - for key, val in attributes.items(): - span.set_attribute(key, val) - return func(*args, **kwargs) - - return wrapper - - -def implement_span_delegator( - obj: _IffHasAttrDescriptor, attributes: Attributes = None -): - """Wrap the descriptor's fn with a span. - - Args: - obj: An instance of _IffHasAttrDescriptor - attributes: Attributes to apply to the span - """ - # Don't instrument inherited delegators - if hasattr(obj, "_otel_original_fn"): - logger.debug("Already instrumented: %s", obj.fn.__qualname__) - return - logger.debug("Instrumenting: %s", obj.fn.__qualname__) - attributes = attributes or {} - setattr(obj, "_otel_original_fn", getattr(obj, "fn")) - setattr( - obj, - "fn", - implement_span_function(obj.fn, obj.fn.__qualname__, attributes), - ) - - -def get_delegator( - estimator: Type[BaseEstimator], method_name: str -) -> Union[_IffHasAttrDescriptor, None]: - """Get the delegator from a class method or None. - - Args: - estimator: A class derived from ``sklearn``'s ``BaseEstimator``. - method_name (str): The method name of the estimator on which to - check for delegation. - - Returns: - The delegator, if one exists, otherwise None. - """ - class_attr = getattr(estimator, method_name) - if getattr(class_attr, "__closure__", None) is not None: - for cell in class_attr.__closure__: - if isinstance(cell.cell_contents, _IffHasAttrDescriptor): - return cell.cell_contents - return None - - -def get_base_estimators(packages: List[str]) -> Dict[str, Type[BaseEstimator]]: - """Walk package hierarchies to get BaseEstimator-derived classes. - - Args: - packages (list(str)): A list of package names to instrument. - - Returns: - A dictionary of qualnames and classes inheriting from - ``BaseEstimator``. - """ - klasses = {} - for package_name in packages: - lib = import_module(package_name) - package_dir = os.path.dirname(lib.__file__) - for _, module_name, _ in iter_modules([package_dir]): - # import the module and iterate through its attributes - try: - module = import_module(package_name + "." + module_name) - except ImportError: - logger.warning( - "Unable to import %s.%s", package_name, module_name - ) - continue - for attribute_name in dir(module): - attrib = getattr(module, attribute_name) - if isclass(attrib) and issubclass(attrib, BaseEstimator): - klasses[ - ".".join([package_name, module_name, attribute_name]) - ] = attrib - return klasses - - -# Methods on which spans should be applied. -DEFAULT_METHODS = [ - "fit", - "transform", - "predict", - "predict_proba", - "_fit", - "_transform", - "_predict", - "_predict_proba", -] - -# Classes and their attributes which contain a list of tupled estimators -# through which we should walk recursively for estimators. -DEFAULT_NAMEDTUPLE_ATTRIBS = { - Pipeline: ["steps"], - FeatureUnion: ["transformer_list"], -} - -# Classes and their attributes which contain an estimator or sequence of -# estimators through which we should walk recursively for estimators. -DEFAULT_ATTRIBS = {} - -# Classes (including children) explicitly excluded from autoinstrumentation -DEFAULT_EXCLUDE_CLASSES = [BaseDecisionTree] - -# Default packages for autoinstrumentation -DEFAULT_PACKAGES = ["sklearn"] - - -class SklearnInstrumentor(BaseInstrumentor): - """Instrument a fitted sklearn model with opentelemetry spans. - - Instrument methods of ``BaseEstimator``-derived components in a sklearn - model. The assumption is that a machine learning model ``Pipeline`` (or - class descendent) is being instrumented with opentelemetry. Within a - ``Pipeline`` is some hierarchy of estimators and transformers. - - The ``instrument_estimator`` method walks this hierarchy of estimators, - implementing each of the defined methods with its own span. - - Certain estimators in the sklearn ecosystem contain other estimators as - instance attributes. Support for walking this embedded sub-hierarchy is - supported with ``recurse_attribs``. This argument is a dictionary - with classes as keys, and a list of attributes representing embedded - estimators as values. By default, ``recurse_attribs`` is empty. - - Similar to Pipelines, there are also estimators which have class attributes - as a list of 2-tuples; for instance, the ``FeatureUnion`` and its attribute - ``transformer_list``. Instrumenting estimators like this is also - supported through the ``recurse_namedtuple_attribs`` argument. This - argument is a dictionary with classes as keys, and a list of attribute - names representing the namedtuple list(s). By default, the - ``recurse_namedtuple_attribs`` dictionary supports - ``Pipeline`` with ``steps``, and ``FeatureUnion`` with - ``transformer_list``. - - Note that spans will not be generated for any child transformer whose - parent transformer has ``n_jobs`` parameter set to anything besides - ``None`` or ``1``. - - Package instrumentation example: - - .. code-block:: python - - from opentelemetry.instrumentation.sklearn import SklearnInstrumentor - - # instrument the sklearn library - SklearnInstrumentor().instrument() - - # instrument several sklearn-compatible libraries - packages = ["sklearn", "lightgbm", "xgboost"] - SklearnInstrumentor(packages=packages).instrument() - - - Model instrumentation example: - - .. code-block:: python - - from opentelemetry.instrumentation.sklearn import SklearnInstrumentor - from sklearn.datasets import load_iris - from sklearn.ensemble import RandomForestClassifier - from sklearn.model_selection import train_test_split - from sklearn.pipeline import Pipeline - - X, y = load_iris(return_X_y=True) - X_train, X_test, y_train, y_test = train_test_split(X, y) - - model = Pipeline( - [ - ("class", RandomForestClassifier(n_estimators=10)), - ] - ) - - model.fit(X_train, y_train) - - SklearnInstrumentor().instrument_estimator(model) - - Args: - methods (list): A list of method names on which to instrument a span. - This list of methods will be checked on all estimators in the model - hierarchy. Used in package and model instrumentation - recurse_attribs (dict): A dictionary of ``BaseEstimator``-derived - sklearn classes as keys, with values being a list of attributes. Each - attribute represents either an estimator or list of estimators on - which to also implement spans. An example is - ``RandomForestClassifier`` and its attribute ``estimators_``. Used - in model instrumentation only. - recurse_namedtuple_attribs (dict): A dictionary of ``BaseEstimator``- - derived sklearn types as keys, with values being a list of - attribute names. Each attribute represents a list of 2-tuples in - which the first element is the estimator name, and the second - element is the estimator. Defaults include sklearn's ``Pipeline`` - and its attribute ``steps``, and the ``FeatureUnion`` and its - attribute ``transformer_list``. Used in model instrumentation only. - packages: A list of sklearn-compatible packages to - instrument. Used with package instrumentation only. - exclude_classes: A list of classes to exclude from instrumentation. - Child classes are also excluded. Default is sklearn's - ``[BaseDecisionTree]``. - """ - - def __new__(cls, *args, **kwargs): - """Override new. - - The base class' new method passes args and kwargs. We override because - we init the class with configuration and Python raises TypeError when - additional arguments are passed to the object.__new__() method. - """ - if cls._instance is None: - cls._instance = object.__new__(cls) - - return cls._instance - - def __init__( - self, - methods: List[str] = None, - recurse_attribs: Dict[Type[BaseEstimator], List[str]] = None, - recurse_namedtuple_attribs: Dict[ - Type[BaseEstimator], List[str] - ] = None, - packages: List[str] = None, - exclude_classes: List[Type] = None, - ): - self.methods = methods or DEFAULT_METHODS - self.recurse_attribs = recurse_attribs or DEFAULT_ATTRIBS - self.recurse_namedtuple_attribs = ( - recurse_namedtuple_attribs or DEFAULT_NAMEDTUPLE_ATTRIBS - ) - self.packages = packages or DEFAULT_PACKAGES - if exclude_classes is None: - self.exclude_classes = tuple(DEFAULT_EXCLUDE_CLASSES) - else: - self.exclude_classes = tuple(exclude_classes) - - def instrumentation_dependencies(self) -> Collection[str]: - return _instruments - - def _instrument(self, **kwargs): - """Instrument the library, and any additional specified on init.""" - klasses = get_base_estimators(packages=self.packages) - attributes = kwargs.get("attributes") - for _, klass in klasses.items(): - if issubclass(klass, self.exclude_classes): - logger.debug("Not instrumenting (excluded): %s", str(klass)) - else: - logger.debug("Instrumenting: %s", str(klass)) - for method_name in self.methods: - if hasattr(klass, method_name): - self._instrument_class_method( - estimator=klass, - method_name=method_name, - attributes=attributes, - ) - - def _uninstrument(self, **kwargs): - """Uninstrument the library""" - klasses = get_base_estimators(packages=self.packages) - for _, klass in klasses.items(): - logger.debug("Uninstrumenting: %s", str(klass)) - for method_name in self.methods: - if hasattr(klass, method_name): - self._uninstrument_class_method( - estimator=klass, method_name=method_name - ) - - def instrument_estimator( - self, estimator: BaseEstimator, attributes: Attributes = None - ): - """Instrument a fitted estimator and its hierarchy where configured. - - Args: - estimator (sklearn.base.BaseEstimator): A fitted ``sklearn`` - estimator, typically a ``Pipeline`` instance. - attributes (dict): Attributes to attach to the spans. - """ - if isinstance(estimator, self.exclude_classes): - logger.debug( - "Not instrumenting (excluded): %s", - estimator.__class__.__name__, - ) - return - - if isinstance( - estimator, tuple(self.recurse_namedtuple_attribs.keys()) - ): - self._instrument_estimator_namedtuple( - estimator=estimator, attributes=attributes - ) - - if isinstance(estimator, tuple(self.recurse_attribs.keys())): - self._instrument_estimator_attribute( - estimator=estimator, attributes=attributes - ) - - for method_name in self.methods: - if hasattr(estimator, method_name): - self._instrument_instance_method( - estimator=estimator, - method_name=method_name, - attributes=attributes, - ) - - def uninstrument_estimator(self, estimator: BaseEstimator): - """Uninstrument a fitted estimator and its hierarchy where configured. - - Args: - estimator (sklearn.base.BaseEstimator): A fitted ``sklearn`` - estimator, typically a ``Pipeline`` instance. - """ - if isinstance(estimator, self.exclude_classes): - logger.debug( - "Not uninstrumenting (excluded): %s", - estimator.__class__.__name__, - ) - return - - if isinstance( - estimator, tuple(self.recurse_namedtuple_attribs.keys()) - ): - self._uninstrument_estimator_namedtuple(estimator=estimator) - - if isinstance(estimator, tuple(self.recurse_attribs.keys())): - self._uninstrument_estimator_attribute(estimator=estimator) - - for method_name in self.methods: - if hasattr(estimator, method_name): - self._uninstrument_instance_method( - estimator=estimator, method_name=method_name - ) - - def _check_instrumented( - self, - estimator: Union[BaseEstimator, Type[BaseEstimator]], - method_name: str, - ) -> bool: - """Check an estimator-method is instrumented. - - Args: - estimator (BaseEstimator): A class or instance of an ``sklearn`` - estimator. - method_name (str): The method name of the estimator on which to - check for instrumentation. - """ - orig_method_name = "_otel_original_" + method_name - has_original = hasattr(estimator, orig_method_name) - orig_class, orig_method = getattr( - estimator, orig_method_name, (None, None) - ) - same_class = orig_class == estimator - if has_original and same_class: - class_method = self._unwrap_function( - getattr(estimator, method_name) - ) - # if they match then the subclass doesn't override - # if they don't then the overridden method needs instrumentation - if class_method.__name__ == orig_method.__name__: - return True - return False - - def _uninstrument_class_method( - self, estimator: Type[BaseEstimator], method_name: str - ): - """Uninstrument a class method. - - Replaces the patched method with the original, and deletes the - attribute which stored the original method. - - Args: - estimator (BaseEstimator): A class or instance of an ``sklearn`` - estimator. - method_name (str): The method name of the estimator on which to - apply a span. - """ - orig_method_name = "_otel_original_" + method_name - if isclass(estimator): - qualname = estimator.__qualname__ - else: - qualname = estimator.__class__.__qualname__ - delegator = get_delegator(estimator, method_name) - if self._check_instrumented(estimator, method_name): - logger.debug( - "Uninstrumenting: %s.%s", - qualname, - method_name, - ) - _, orig_method = getattr(estimator, orig_method_name) - setattr( - estimator, - method_name, - orig_method, - ) - delattr(estimator, orig_method_name) - elif delegator is not None: - if not hasattr(delegator, "_otel_original_fn"): - logger.debug( - "Already uninstrumented: %s.%s", - qualname, - method_name, - ) - return - setattr( - delegator, - "fn", - getattr(delegator, "_otel_original_fn"), - ) - delattr(delegator, "_otel_original_fn") - else: - logger.debug( - "Already uninstrumented: %s.%s", - qualname, - method_name, - ) - - def _uninstrument_instance_method( - self, estimator: BaseEstimator, method_name: str - ): - """Uninstrument an instance method. - - Replaces the patched method with the original, and deletes the - attribute which stored the original method. - - Args: - estimator (BaseEstimator): A class or instance of an ``sklearn`` - estimator. - method_name (str): The method name of the estimator on which to - apply a span. - """ - orig_method_name = "_otel_original_" + method_name - if isclass(estimator): - qualname = estimator.__qualname__ - else: - qualname = estimator.__class__.__qualname__ - if self._check_instrumented(estimator, method_name): - logger.debug( - "Uninstrumenting: %s.%s", - qualname, - method_name, - ) - _, orig_method = getattr(estimator, orig_method_name) - setattr( - estimator, - method_name, - orig_method, - ) - delattr(estimator, orig_method_name) - else: - logger.debug( - "Already uninstrumented: %s.%s", - qualname, - method_name, - ) - - def _instrument_class_method( - self, - estimator: Type[BaseEstimator], - method_name: str, - attributes: Attributes = None, - ): - """Instrument an estimator method with a span. - - When instrumenting we attach a tuple of (Class, method) to the - attribute ``_otel_original_`` for each method. This allows - us to replace the patched with the original in uninstrumentation, but - also allows proper instrumentation of child classes without - instrumenting inherited methods twice. - - Args: - estimator (BaseEstimator): A ``BaseEstimator``-derived - class - method_name (str): The method name of the estimator on which to - apply a span. - attributes (dict): Attributes to attach to the spans. - """ - if self._check_instrumented(estimator, method_name): - logger.debug( - "Already instrumented: %s.%s", - estimator.__qualname__, - method_name, - ) - return - class_attr = getattr(estimator, method_name) - delegator = get_delegator(estimator, method_name) - if isinstance(class_attr, property): - logger.debug( - "Not instrumenting found property: %s.%s", - estimator.__qualname__, - method_name, - ) - elif delegator is not None: - implement_span_delegator(delegator) - else: - setattr( - estimator, - "_otel_original_" + method_name, - (estimator, class_attr), - ) - setattr( - estimator, - method_name, - implement_span_estimator(class_attr, estimator, attributes), - ) - - def _unwrap_function(self, function): - """Fetch the function underlying any decorators""" - if hasattr(function, "__wrapped__"): - return self._unwrap_function(function.__wrapped__) - return function - - def _instrument_instance_method( - self, - estimator: BaseEstimator, - method_name: str, - attributes: Attributes = None, - ): - """Instrument an estimator instance method with a span. - - When instrumenting we attach a tuple of (Class, method) to the - attribute ``_otel_original_`` for each method. This allows - us to replace the patched with the original in unstrumentation. - - Args: - estimator (BaseEstimator): A fitted ``sklearn`` estimator. - method_name (str): The method name of the estimator on which to - apply a span. - attributes (dict): Attributes to attach to the spans. - """ - if self._check_instrumented(estimator, method_name): - logger.debug( - "Already instrumented: %s.%s", - estimator.__class__.__qualname__, - method_name, - ) - return - - class_attr = getattr(type(estimator), method_name, None) - if isinstance(class_attr, property): - logger.debug( - "Not instrumenting found property: %s.%s", - estimator.__class__.__qualname__, - method_name, - ) - else: - method = getattr(estimator, method_name) - setattr( - estimator, "_otel_original_" + method_name, (estimator, method) - ) - setattr( - estimator, - method_name, - implement_span_estimator(method, estimator, attributes), - ) - - def _instrument_estimator_attribute( - self, estimator: BaseEstimator, attributes: Attributes = None - ): - """Instrument instance attributes which also contain estimators. - - Handle instance attributes which are also estimators, are a list - (Sequence) of estimators, or are mappings (dictionary) in which - the values are estimators. - - Examples include ``RandomForestClassifier`` and - ``MultiOutputRegressor`` instances which have attributes - ``estimators_`` attributes. - - Args: - estimator (BaseEstimator): A fitted ``sklearn`` estimator, with an - attribute which also contains an estimator or collection of - estimators. - attributes (dict): Attributes to attach to the spans. - """ - attribs = self.recurse_attribs.get(estimator.__class__, []) - for attrib in attribs: - attrib_value = getattr(estimator, attrib) - if isinstance(attrib_value, Sequence): - for value in attrib_value: - self.instrument_estimator( - estimator=value, attributes=attributes - ) - elif isinstance(attrib_value, MutableMapping): - for value in attrib_value.values(): - self.instrument_estimator( - estimator=value, attributes=attributes - ) - else: - self.instrument_estimator( - estimator=attrib_value, attributes=attributes - ) - - def _instrument_estimator_namedtuple( - self, estimator: BaseEstimator, attributes: Attributes = None - ): - """Instrument attributes with (name, estimator) tupled components. - - Examples include Pipeline and FeatureUnion instances which - have attributes steps and transformer_list, respectively. - - Args: - estimator: A fitted sklearn estimator, with an attribute which also - contains an estimator or collection of estimators. - attributes (dict): Attributes to attach to the spans. - """ - attribs = self.recurse_namedtuple_attribs.get(estimator.__class__, []) - for attrib in attribs: - for _, est in getattr(estimator, attrib): - self.instrument_estimator(estimator=est, attributes=attributes) - - def _uninstrument_estimator_attribute(self, estimator: BaseEstimator): - """Uninstrument instance attributes which also contain estimators. - - Handle instance attributes which are also estimators, are a list - (Sequence) of estimators, or are mappings (dictionary) in which - the values are estimators. - - Examples include ``RandomForestClassifier`` and - ``MultiOutputRegressor`` instances which have attributes - ``estimators_`` attributes. - - Args: - estimator (BaseEstimator): A fitted ``sklearn`` estimator, with an - attribute which also contains an estimator or collection of - estimators. - """ - attribs = self.recurse_attribs.get(estimator.__class__, []) - for attrib in attribs: - attrib_value = getattr(estimator, attrib) - if isinstance(attrib_value, Sequence): - for value in attrib_value: - self.uninstrument_estimator(estimator=value) - elif isinstance(attrib_value, MutableMapping): - for value in attrib_value.values(): - self.uninstrument_estimator(estimator=value) - else: - self.uninstrument_estimator(estimator=attrib_value) - - def _uninstrument_estimator_namedtuple(self, estimator: BaseEstimator): - """Uninstrument attributes with (name, estimator) tupled components. - - Examples include Pipeline and FeatureUnion instances which - have attributes steps and transformer_list, respectively. - - Args: - estimator: A fitted sklearn estimator, with an attribute which also - contains an estimator or collection of estimators. - """ - attribs = self.recurse_namedtuple_attribs.get(estimator.__class__, []) - for attrib in attribs: - for _, est in getattr(estimator, attrib): - self.uninstrument_estimator(estimator=est) diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/package.py b/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/package.py deleted file mode 100644 index 41db461453..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/package.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -_instruments = ("scikit-learn ~= 0.24.0",) diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py b/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py deleted file mode 100644 index deef26c62f..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/src/opentelemetry/instrumentation/sklearn/version.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__version__ = "0.47b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt deleted file mode 100644 index af341e16ed..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt +++ /dev/null @@ -1,19 +0,0 @@ -asgiref==3.7.2 -Deprecated==1.2.14 -importlib-metadata==6.11.0 -iniconfig==2.0.0 -joblib==1.3.2 -numpy==1.24.4 -packaging==24.0 -pluggy==1.5.0 -py-cpuinfo==9.0.0 -pytest==7.4.4 -scikit-learn==0.24.2 -scipy==1.10.1 -threadpoolctl==3.3.0 -tomli==2.0.1 -typing_extensions==4.10.0 -wrapt==1.16.0 -zipp==3.19.2 --e opentelemetry-instrumentation --e instrumentation/opentelemetry-instrumentation-sklearn diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-sklearn/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/tests/fixtures.py b/instrumentation/opentelemetry-instrumentation-sklearn/tests/fixtures.py deleted file mode 100644 index cf26c0fcf2..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/tests/fixtures.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import numpy as np -from sklearn.datasets import load_iris -from sklearn.decomposition import PCA, TruncatedSVD -from sklearn.ensemble import RandomForestClassifier -from sklearn.model_selection import train_test_split -from sklearn.pipeline import FeatureUnion, Pipeline -from sklearn.preprocessing import Normalizer, StandardScaler - -X, y = load_iris(return_X_y=True) -X_train, X_test, y_train, y_test = train_test_split(X, y) - - -def pipeline(): - """A dummy model that has a bunch of components that we can test.""" - model = Pipeline( - [ - ("scaler", StandardScaler()), - ("normal", Normalizer()), - ( - "union", - FeatureUnion( - [ - ("pca", PCA(n_components=1)), - ("svd", TruncatedSVD(n_components=2)), - ], - n_jobs=1, # parallelized components won't generate spans - ), - ), - ("class", RandomForestClassifier(n_estimators=10)), - ] - ) - model.fit(X_train, y_train) - return model - - -def random_input(): - """A random record from the feature set.""" - rows = X.shape[0] - random_row = np.random.choice(rows, size=1) - return X[random_row, :] diff --git a/instrumentation/opentelemetry-instrumentation-sklearn/tests/test_sklearn.py b/instrumentation/opentelemetry-instrumentation-sklearn/tests/test_sklearn.py deleted file mode 100644 index db69761ece..0000000000 --- a/instrumentation/opentelemetry-instrumentation-sklearn/tests/test_sklearn.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright 2020, OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from sklearn.ensemble import RandomForestClassifier - -# pylint: disable=no-name-in-module -from opentelemetry.instrumentation.sklearn import ( - DEFAULT_EXCLUDE_CLASSES, - DEFAULT_METHODS, - SklearnInstrumentor, - get_base_estimators, - get_delegator, -) -from opentelemetry.test.test_base import TestBase -from opentelemetry.trace import SpanKind - -from .fixtures import pipeline, random_input - - -def assert_instrumented(base_estimators): - for _, estimator in base_estimators.items(): - for method_name in DEFAULT_METHODS: - original_method_name = "_otel_original_" + method_name - if issubclass(estimator, tuple(DEFAULT_EXCLUDE_CLASSES)): - assert not hasattr(estimator, original_method_name) - continue - class_attr = getattr(estimator, method_name, None) - if isinstance(class_attr, property): - assert not hasattr(estimator, original_method_name) - continue - delegator = None - if hasattr(estimator, method_name): - delegator = get_delegator(estimator, method_name) - if delegator is not None: - assert hasattr(delegator, "_otel_original_fn") - elif hasattr(estimator, method_name): - assert hasattr(estimator, original_method_name) - - -def assert_uninstrumented(base_estimators): - for _, estimator in base_estimators.items(): - for method_name in DEFAULT_METHODS: - original_method_name = "_otel_original_" + method_name - if issubclass(estimator, tuple(DEFAULT_EXCLUDE_CLASSES)): - assert not hasattr(estimator, original_method_name) - continue - class_attr = getattr(estimator, method_name, None) - if isinstance(class_attr, property): - assert not hasattr(estimator, original_method_name) - continue - delegator = None - if hasattr(estimator, method_name): - delegator = get_delegator(estimator, method_name) - if delegator is not None: - assert not hasattr(delegator, "_otel_original_fn") - elif hasattr(estimator, method_name): - assert not hasattr(estimator, original_method_name) - - -class TestSklearn(TestBase): - def test_package_instrumentation(self): - ski = SklearnInstrumentor() - - base_estimators = get_base_estimators(packages=["sklearn"]) - - model = pipeline() - - ski.instrument() - assert_instrumented(base_estimators) - - x_test = random_input() - - model.predict(x_test) - - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 8) - self.memory_exporter.clear() - - ski.uninstrument() - assert_uninstrumented(base_estimators) - - model = pipeline() - x_test = random_input() - - model.predict(x_test) - - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 0) - - def test_span_properties(self): - """Test that we get all of the spans we expect.""" - model = pipeline() - ski = SklearnInstrumentor() - ski.instrument_estimator(estimator=model) - - x_test = random_input() - - model.predict(x_test) - - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 8) - span = spans[0] - self.assertEqual(span.name, "StandardScaler.transform") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[-1].context.span_id) - span = spans[1] - self.assertEqual(span.name, "Normalizer.transform") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[-1].context.span_id) - span = spans[2] - self.assertEqual(span.name, "PCA.transform") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[4].context.span_id) - span = spans[3] - self.assertEqual(span.name, "TruncatedSVD.transform") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[4].context.span_id) - span = spans[4] - self.assertEqual(span.name, "FeatureUnion.transform") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[-1].context.span_id) - span = spans[5] - self.assertEqual(span.name, "RandomForestClassifier.predict_proba") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[6].context.span_id) - span = spans[6] - self.assertEqual(span.name, "RandomForestClassifier.predict") - self.assertEqual(span.kind, SpanKind.INTERNAL) - self.assertEqual(span.parent.span_id, spans[-1].context.span_id) - span = spans[7] - self.assertEqual(span.name, "Pipeline.predict") - self.assertEqual(span.kind, SpanKind.INTERNAL) - - self.memory_exporter.clear() - - # uninstrument - ski.uninstrument_estimator(estimator=model) - x_test = random_input() - model.predict(x_test) - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 0) - - def test_attrib_config(self): - """Test that the attribute config makes spans on the decision trees.""" - model = pipeline() - attrib_config = {RandomForestClassifier: ["estimators_"]} - ski = SklearnInstrumentor( - recurse_attribs=attrib_config, - exclude_classes=[], # decision trees excluded by default - ) - ski.instrument_estimator(estimator=model) - - x_test = random_input() - model.predict(x_test) - - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 8 + model.steps[-1][-1].n_estimators) - - self.memory_exporter.clear() - - ski.uninstrument_estimator(estimator=model) - x_test = random_input() - model.predict(x_test) - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 0) - - def test_span_attributes(self): - model = pipeline() - attributes = {"model_name": "random_forest_model"} - ski = SklearnInstrumentor() - ski.instrument_estimator(estimator=model, attributes=attributes) - - x_test = random_input() - - model.predict(x_test) - - spans = self.memory_exporter.get_finished_spans() - for span in spans: - assert span.attributes["model_name"] == "random_forest_model" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 74c28f38cf..f83b9d5ee5 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -66,7 +66,6 @@ dependencies = [ "opentelemetry-instrumentation-redis==0.47b0.dev", "opentelemetry-instrumentation-remoulade==0.47b0.dev", "opentelemetry-instrumentation-requests==0.47b0.dev", - "opentelemetry-instrumentation-sklearn==0.47b0.dev", "opentelemetry-instrumentation-sqlalchemy==0.47b0.dev", "opentelemetry-instrumentation-sqlite3==0.47b0.dev", "opentelemetry-instrumentation-starlette==0.47b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 3dfd97e0b2..3f4c78862f 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -152,10 +152,6 @@ "library": "requests ~= 2.0", "instrumentation": "opentelemetry-instrumentation-requests==0.47b0.dev", }, - { - "library": "scikit-learn ~= 0.24.0", - "instrumentation": "opentelemetry-instrumentation-sklearn==0.47b0.dev", - }, { "library": "sqlalchemy", "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.47b0.dev", diff --git a/tox.ini b/tox.ini index 529e2a76c0..aac890ed7c 100644 --- a/tox.ini +++ b/tox.ini @@ -273,10 +273,6 @@ envlist = pypy3-test-instrumentation-celery lint-instrumentation-celery - ; opentelemetry-instrumentation-sklearn - py3{8}-test-instrumentation-sklearn - lint-instrumentation-sklearn - ; opentelemetry-instrumentation-system-metrics py3{8,9,10,11,12}-test-instrumentation-system-metrics pypy3-test-instrumentation-system-metrics @@ -701,12 +697,6 @@ commands_pre = prometheus: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils prometheus: pip install -r {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt - sklearn: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - sklearn: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - sklearn: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - sklearn: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - sklearn: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn/test-requirements.txt - sqlalchemy: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api sqlalchemy: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions sqlalchemy: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -1021,12 +1011,6 @@ commands = lint-instrumentation-requests: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-requests lint-instrumentation-requests: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-requests" - test-instrumentation-sklearn: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn/tests {posargs} - lint-instrumentation-sklearn: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn - lint-instrumentation-sklearn: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn - lint-instrumentation-sklearn: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn - lint-instrumentation-sklearn: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-sklearn" - test-instrumentation-sqlalchemy: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests {posargs} lint-instrumentation-sqlalchemy: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy lint-instrumentation-sqlalchemy: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy From e6c27e08007c4acf2a3fa9f903c52c4656b9ea62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:46:31 -0300 Subject: [PATCH 103/335] Add support to instrument httpx when using proxy (#2664) --- CHANGELOG.md | 4 +- .../instrumentation/httpx/__init__.py | 69 +++++++++ .../tests/test_httpx_integration.py | 139 +++++++++++++++++- 3 files changed, 205 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2de76b2736..98bbd3a0bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2630](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2630)) - `opentelemetry-instrumentation-system-metrics` Add support for capture open file descriptors ([#2652](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2652)) +- `opentelemetry-instrumentation-httpx` Add support for instrument client with proxy + ([#2664](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2664)) - `opentelemetry-instrumentation-aiohttp-client` Implement new semantic convention opt-in migration ([#2673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2673)) - `opentelemetry-instrumentation-django` Add `http.target` to Django duration metric attributes @@ -63,7 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-asgi` Fix generation of `http.target` and `http.url` attributes for ASGI apps using sub apps ([#2477](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2477)) -- `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. +- `opentelemetry-instrumentation-aws-lambda` Bugfix: AWS Lambda event source key incorrect for SNS in instrumentation library. ([#2612](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2612)) - `opentelemetry-instrumentation-asyncio` instrumented `asyncio.wait_for` properly raises `asyncio.TimeoutError` as expected ([#2637](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2637)) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index d2ff0be292..e3ce383d7e 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -640,6 +640,7 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._original_transport = self._transport + self._original_mounts = self._mounts.copy() self._is_instrumented_by_opentelemetry = True self._transport = SyncOpenTelemetryTransport( @@ -648,6 +649,21 @@ def __init__(self, *args, **kwargs): request_hook=_InstrumentedClient._request_hook, response_hook=_InstrumentedClient._response_hook, ) + self._mounts.update( + { + url_pattern: ( + SyncOpenTelemetryTransport( + transport, + tracer_provider=_InstrumentedClient._tracer_provider, + request_hook=_InstrumentedClient._request_hook, + response_hook=_InstrumentedClient._response_hook, + ) + if transport is not None + else transport + ) + for url_pattern, transport in self._original_mounts.items() + } + ) class _InstrumentedAsyncClient(httpx.AsyncClient): @@ -659,6 +675,7 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._original_transport = self._transport + self._original_mounts = self._mounts.copy() self._is_instrumented_by_opentelemetry = True self._transport = AsyncOpenTelemetryTransport( @@ -668,6 +685,22 @@ def __init__(self, *args, **kwargs): response_hook=_InstrumentedAsyncClient._response_hook, ) + self._mounts.update( + { + url_pattern: ( + AsyncOpenTelemetryTransport( + transport, + tracer_provider=_InstrumentedAsyncClient._tracer_provider, + request_hook=_InstrumentedAsyncClient._request_hook, + response_hook=_InstrumentedAsyncClient._response_hook, + ) + if transport is not None + else transport + ) + for url_pattern, transport in self._original_mounts.items() + } + ) + class HTTPXClientInstrumentor(BaseInstrumentor): # pylint: disable=protected-access,attribute-defined-outside-init @@ -752,6 +785,7 @@ def instrument_client( if not client._is_instrumented_by_opentelemetry: if isinstance(client, httpx.Client): client._original_transport = client._transport + client._original_mounts = client._mounts.copy() transport = client._transport or httpx.HTTPTransport() client._transport = SyncOpenTelemetryTransport( transport, @@ -760,8 +794,25 @@ def instrument_client( response_hook=response_hook, ) client._is_instrumented_by_opentelemetry = True + client._mounts.update( + { + url_pattern: ( + SyncOpenTelemetryTransport( + transport, + tracer_provider=tracer_provider, + request_hook=request_hook, + response_hook=response_hook, + ) + if transport is not None + else transport + ) + for url_pattern, transport in client._original_mounts.items() + } + ) + if isinstance(client, httpx.AsyncClient): transport = client._transport or httpx.AsyncHTTPTransport() + client._original_mounts = client._mounts.copy() client._transport = AsyncOpenTelemetryTransport( transport, tracer_provider=tracer_provider, @@ -769,6 +820,21 @@ def instrument_client( response_hook=response_hook, ) client._is_instrumented_by_opentelemetry = True + client._mounts.update( + { + url_pattern: ( + AsyncOpenTelemetryTransport( + transport, + tracer_provider=tracer_provider, + request_hook=request_hook, + response_hook=response_hook, + ) + if transport is not None + else transport + ) + for url_pattern, transport in client._original_mounts.items() + } + ) else: _logger.warning( "Attempting to instrument Httpx client while already instrumented" @@ -787,6 +853,9 @@ def uninstrument_client( client._transport = client._original_transport del client._original_transport client._is_instrumented_by_opentelemetry = False + if hasattr(client, "_original_mounts"): + client._mounts = client._original_mounts.copy() + del client._original_mounts else: _logger.warning( "Attempting to uninstrument Httpx " diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 84bab598e6..03141e61b5 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -530,6 +530,7 @@ def create_transport( tracer_provider: typing.Optional["TracerProvider"] = None, request_hook: typing.Optional["RequestHook"] = None, response_hook: typing.Optional["ResponseHook"] = None, + **kwargs, ): pass @@ -539,6 +540,7 @@ def create_client( transport: typing.Union[ SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport, None ] = None, + **kwargs, ): pass @@ -643,6 +645,30 @@ def test_not_recording_not_set_attribute_in_exception_new_semconv( self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) + @respx.mock + def test_client_mounts_with_instrumented_transport(self): + https_url = "https://mock/status/200" + respx.get(https_url).mock(httpx.Response(200)) + proxy_mounts = { + "http://": self.create_transport( + proxy=httpx.Proxy("http://localhost:8080") + ), + "https://": self.create_transport( + proxy=httpx.Proxy("http://localhost:8443") + ), + } + client1 = self.create_client(mounts=proxy_mounts) + client2 = self.create_client(mounts=proxy_mounts) + self.perform_request(self.URL, client=client1) + self.perform_request(https_url, client=client2) + spans = self.assert_span(num_spans=2) + self.assertEqual( + spans[0].attributes[SpanAttributes.HTTP_URL], self.URL + ) + self.assertEqual( + spans[1].attributes[SpanAttributes.HTTP_URL], https_url + ) + class BaseInstrumentorTest(BaseTest, metaclass=abc.ABCMeta): @abc.abstractmethod def create_client( @@ -650,15 +676,39 @@ def create_client( transport: typing.Union[ SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport, None ] = None, + **kwargs, ): pass + @abc.abstractmethod + def create_proxy_transport(self, url: str): + pass + def setUp(self): super().setUp() HTTPXClientInstrumentor().instrument() self.client = self.create_client() HTTPXClientInstrumentor().uninstrument() + def create_proxy_mounts(self): + return { + "http://": self.create_proxy_transport( + "http://localhost:8080" + ), + "https://": self.create_proxy_transport( + "http://localhost:8080" + ), + } + + def assert_proxy_mounts(self, mounts, num_mounts, transport_type): + self.assertEqual(len(mounts), num_mounts) + for transport in mounts: + with self.subTest(transport): + self.assertIsInstance( + transport, + transport_type, + ) + def test_custom_tracer_provider(self): resource = resources.Resource.create({}) result = self.create_tracer_provider(resource=resource) @@ -855,6 +905,71 @@ def test_uninstrument_new_client(self): self.assertEqual(result.text, "Hello!") self.assert_span() + def test_instrument_proxy(self): + proxy_mounts = self.create_proxy_mounts() + HTTPXClientInstrumentor().instrument() + client = self.create_client(mounts=proxy_mounts) + self.perform_request(self.URL, client=client) + self.assert_span(num_spans=1) + self.assert_proxy_mounts( + client._mounts.values(), + 2, + (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), + ) + HTTPXClientInstrumentor().uninstrument() + + def test_instrument_client_with_proxy(self): + proxy_mounts = self.create_proxy_mounts() + client = self.create_client(mounts=proxy_mounts) + self.assert_proxy_mounts( + client._mounts.values(), + 2, + (httpx.HTTPTransport, httpx.AsyncHTTPTransport), + ) + HTTPXClientInstrumentor().instrument_client(client) + result = self.perform_request(self.URL, client=client) + self.assertEqual(result.text, "Hello!") + self.assert_span(num_spans=1) + self.assert_proxy_mounts( + client._mounts.values(), + 2, + (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), + ) + HTTPXClientInstrumentor().uninstrument_client(client) + + def test_uninstrument_client_with_proxy(self): + proxy_mounts = self.create_proxy_mounts() + HTTPXClientInstrumentor().instrument() + client = self.create_client(mounts=proxy_mounts) + self.assert_proxy_mounts( + client._mounts.values(), + 2, + (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), + ) + + HTTPXClientInstrumentor().uninstrument_client(client) + result = self.perform_request(self.URL, client=client) + + self.assertEqual(result.text, "Hello!") + self.assert_span(num_spans=0) + self.assert_proxy_mounts( + client._mounts.values(), + 2, + (httpx.HTTPTransport, httpx.AsyncHTTPTransport), + ) + # Test that other clients as well as instance client is still + # instrumented + client2 = self.create_client() + result = self.perform_request(self.URL, client=client2) + self.assertEqual(result.text, "Hello!") + self.assert_span() + + self.memory_exporter.clear() + + result = self.perform_request(self.URL) + self.assertEqual(result.text, "Hello!") + self.assert_span() + class TestSyncIntegration(BaseTestCases.BaseManualTest): def setUp(self): @@ -871,8 +986,9 @@ def create_transport( tracer_provider: typing.Optional["TracerProvider"] = None, request_hook: typing.Optional["RequestHook"] = None, response_hook: typing.Optional["ResponseHook"] = None, + **kwargs, ): - transport = httpx.HTTPTransport() + transport = httpx.HTTPTransport(**kwargs) telemetry_transport = SyncOpenTelemetryTransport( transport, tracer_provider=tracer_provider, @@ -884,8 +1000,9 @@ def create_transport( def create_client( self, transport: typing.Optional[SyncOpenTelemetryTransport] = None, + **kwargs, ): - return httpx.Client(transport=transport) + return httpx.Client(transport=transport, **kwargs) def perform_request( self, @@ -921,8 +1038,9 @@ def create_transport( tracer_provider: typing.Optional["TracerProvider"] = None, request_hook: typing.Optional["AsyncRequestHook"] = None, response_hook: typing.Optional["AsyncResponseHook"] = None, + **kwargs, ): - transport = httpx.AsyncHTTPTransport() + transport = httpx.AsyncHTTPTransport(**kwargs) telemetry_transport = AsyncOpenTelemetryTransport( transport, tracer_provider=tracer_provider, @@ -934,8 +1052,9 @@ def create_transport( def create_client( self, transport: typing.Optional[AsyncOpenTelemetryTransport] = None, + **kwargs, ): - return httpx.AsyncClient(transport=transport) + return httpx.AsyncClient(transport=transport, **kwargs) def perform_request( self, @@ -977,8 +1096,9 @@ class TestSyncInstrumentationIntegration(BaseTestCases.BaseInstrumentorTest): def create_client( self, transport: typing.Optional[SyncOpenTelemetryTransport] = None, + **kwargs, ): - return httpx.Client() + return httpx.Client(**kwargs) def perform_request( self, @@ -991,6 +1111,9 @@ def perform_request( return self.client.request(method, url, headers=headers) return client.request(method, url, headers=headers) + def create_proxy_transport(self, url): + return httpx.HTTPTransport(proxy=httpx.Proxy(url)) + class TestAsyncInstrumentationIntegration(BaseTestCases.BaseInstrumentorTest): response_hook = staticmethod(_async_response_hook) @@ -1007,8 +1130,9 @@ def setUp(self): def create_client( self, transport: typing.Optional[AsyncOpenTelemetryTransport] = None, + **kwargs, ): - return httpx.AsyncClient() + return httpx.AsyncClient(**kwargs) def perform_request( self, @@ -1027,6 +1151,9 @@ async def _perform_request(): return _async_call(_perform_request()) + def create_proxy_transport(self, url): + return httpx.AsyncHTTPTransport(proxy=httpx.Proxy(url)) + def test_basic_multiple(self): # We need to create separate clients because in httpx >= 0.19, # closing the client after "with" means the second http call fails From 05073008a3644087721c7a61e3776fbc1173fe09 Mon Sep 17 00:00:00 2001 From: Chris Guidry Date: Thu, 18 Jul 2024 13:11:04 -0400 Subject: [PATCH 104/335] Re-raise `redis.WatchError`s when they occur (#2721) --- .../instrumentation/redis/__init__.py | 21 +++++++++++++++---- .../tests/test_redis.py | 8 ++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index c5f19fc736..08337c2d4a 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -203,6 +203,8 @@ def _traced_execute_pipeline(func, instance, args, kwargs): span_name, ) = _build_span_meta_data_for_pipeline(instance) + exception = None + with tracer.start_as_current_span( span_name, kind=trace.SpanKind.CLIENT ) as span: @@ -216,13 +218,17 @@ def _traced_execute_pipeline(func, instance, args, kwargs): response = None try: response = func(*args, **kwargs) - except redis.WatchError: + except redis.WatchError as watch_exception: span.set_status(StatusCode.UNSET) + exception = watch_exception if callable(response_hook): response_hook(span, instance, response) - return response + if exception: + raise exception + + return response pipeline_class = ( "BasePipeline" if redis.VERSION < (3, 0, 0) else "Pipeline" @@ -279,6 +285,8 @@ async def _async_traced_execute_pipeline(func, instance, args, kwargs): span_name, ) = _build_span_meta_data_for_pipeline(instance) + exception = None + with tracer.start_as_current_span( span_name, kind=trace.SpanKind.CLIENT ) as span: @@ -292,12 +300,17 @@ async def _async_traced_execute_pipeline(func, instance, args, kwargs): response = None try: response = await func(*args, **kwargs) - except redis.WatchError: + except redis.WatchError as watch_exception: span.set_status(StatusCode.UNSET) + exception = watch_exception if callable(response_hook): response_hook(span, instance, response) - return response + + if exception: + raise exception + + return response if redis.VERSION >= _REDIS_ASYNCIO_VERSION: wrap_function_wrapper( diff --git a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py index 23d21b6e5a..c436589adb 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py +++ b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py @@ -359,7 +359,7 @@ def test_response_error(self): def test_watch_error_sync(self): def redis_operations(): - try: + with pytest.raises(WatchError): redis_client = fakeredis.FakeStrictRedis() pipe = redis_client.pipeline(transaction=True) pipe.watch("a") @@ -367,8 +367,6 @@ def redis_operations(): pipe.multi() pipe.set("a", "1") pipe.execute() - except WatchError: - pass redis_operations() @@ -400,7 +398,7 @@ def tearDown(self): @pytest.mark.asyncio async def test_watch_error_async(self): async def redis_operations(): - try: + with pytest.raises(WatchError): redis_client = FakeRedis() async with redis_client.pipeline(transaction=False) as pipe: await pipe.watch("a") @@ -408,8 +406,6 @@ async def redis_operations(): pipe.multi() await pipe.set("a", "1") await pipe.execute() - except WatchError: - pass await redis_operations() From fa23d8a7a057db2548bb9d0d9f1a5ca618dbd5fe Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 18 Jul 2024 16:47:07 -0700 Subject: [PATCH 105/335] Re-add `opentelemetry-instrumentation-aiohttp-server` to release script (#2722) * Update .pylintrc * Update build.sh --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 93dc0edce1..69df4f7748 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -32,7 +32,7 @@ DISTDIR=dist cd $DISTDIR for x in * ; do # FIXME: Remove this logic once these packages are available in Pypi - if echo "$x" | grep -Eq "^opentelemetry_(instrumentation_aiohttp_server|resource_detector_container).*(\.tar\.gz|\.whl)$"; then + if echo "$x" | grep -Eq "^opentelemetry_resource_detector_container.*(\.tar\.gz|\.whl)$"; then echo "Skipping $x because of erroneous uploads. See: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2053" rm $x # FIXME: Remove this once opentelemetry-resource-detector-azure package goes 1.X From 6594cdf0538ad0bedf77f602870134cc88a8fc12 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 22 Jul 2024 18:16:46 +0200 Subject: [PATCH 106/335] resource/azure: make the version of opentelemetry-instrument more relaxed (#2725) --- resource/opentelemetry-resource-detector-azure/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index fec99ef157..14952b751c 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-sdk ~= 1.21", - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation ~= 0.43b0", ] [project.entry-points.opentelemetry_resource_detector] From a322a0a26b8c62f5c2c58fab2eefc2aac2b11391 Mon Sep 17 00:00:00 2001 From: GonzaloGuasch Date: Mon, 22 Jul 2024 13:33:40 -0300 Subject: [PATCH 107/335] flask: add `http.target` and `http.route` to metric attributes (#2621) --- CHANGELOG.md | 2 ++ .../instrumentation/flask/__init__.py | 15 +++++++++++++++ .../tests/test_programmatic.py | 16 ++++++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98bbd3a0bc..5ed29f8ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-flask` Add `http.route` and `http.target` to metric attributes + ([#2621](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2621)) - `opentelemetry-instrumentation-sklearn` Deprecated the sklearn instrumentation ([#2708](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2708)) - `opentelemetry-instrumentation-pyramid` Record exceptions raised when serving a request 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 eaf6c79506..9bc5e85a12 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -266,6 +266,7 @@ def response_hook(span: Span, status: str, response_headers: List): ) from opentelemetry.instrumentation.utils import _start_internal_or_server_span from opentelemetry.metrics import get_meter +from opentelemetry.semconv.attributes.http_attributes import HTTP_ROUTE from opentelemetry.semconv.metrics import MetricInstruments from opentelemetry.semconv.metrics.http_metrics import ( HTTP_SERVER_REQUEST_DURATION, @@ -340,12 +341,16 @@ def _wrapped_app(wrapped_app_environ, start_response): ) active_requests_counter.add(1, active_requests_count_attrs) + request_route = None def _start_response(status, response_headers, *args, **kwargs): if flask.request and ( excluded_urls is None or not excluded_urls.url_disabled(flask.request.url) ): + nonlocal request_route + request_route = flask.request.url_rule + span = flask.request.environ.get(_ENVIRON_SPAN_KEY) propagator = get_global_response_propagator() @@ -388,6 +393,12 @@ def _start_response(status, response_headers, *args, **kwargs): duration_attrs_old = otel_wsgi._parse_duration_attrs( attributes, _HTTPStabilityMode.DEFAULT ) + + if request_route: + duration_attrs_old[SpanAttributes.HTTP_TARGET] = str( + request_route + ) + duration_histogram_old.record( max(round(duration_s * 1000), 0), duration_attrs_old ) @@ -395,6 +406,10 @@ def _start_response(status, response_headers, *args, **kwargs): duration_attrs_new = otel_wsgi._parse_duration_attrs( attributes, _HTTPStabilityMode.HTTP ) + + if request_route: + duration_attrs_new[HTTP_ROUTE] = str(request_route) + duration_histogram_new.record( max(duration_s, 0), duration_attrs_new ) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 94437bbfd2..4458daae21 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -85,6 +85,12 @@ def expected_attributes_new(override_attributes): return default_attributes +_server_duration_attrs_old_copy = _server_duration_attrs_old.copy() +_server_duration_attrs_old_copy.append("http.target") + +_server_duration_attrs_new_copy = _server_duration_attrs_new.copy() +_server_duration_attrs_new_copy.append("http.route") + _expected_metric_names_old = [ "http.server.active_requests", "http.server.duration", @@ -95,11 +101,11 @@ def expected_attributes_new(override_attributes): ] _recommended_metrics_attrs_old = { "http.server.active_requests": _server_active_requests_count_attrs_old, - "http.server.duration": _server_duration_attrs_old, + "http.server.duration": _server_duration_attrs_old_copy, } _recommended_metrics_attrs_new = { "http.server.active_requests": _server_active_requests_count_attrs_new, - "http.server.request.duration": _server_duration_attrs_new, + "http.server.request.duration": _server_duration_attrs_new_copy, } _server_active_requests_count_attrs_both = ( _server_active_requests_count_attrs_old @@ -109,8 +115,8 @@ def expected_attributes_new(override_attributes): ) _recommended_metrics_attrs_both = { "http.server.active_requests": _server_active_requests_count_attrs_both, - "http.server.duration": _server_duration_attrs_old, - "http.server.request.duration": _server_duration_attrs_new, + "http.server.duration": _server_duration_attrs_old_copy, + "http.server.request.duration": _server_duration_attrs_new_copy, } @@ -570,6 +576,7 @@ def test_basic_metric_success(self): self.client.get("/hello/756") expected_duration_attributes = { "http.method": "GET", + "http.target": "/hello/", "http.host": "localhost", "http.scheme": "http", "http.flavor": "1.1", @@ -595,6 +602,7 @@ def test_basic_metric_success_new_semconv(self): expected_duration_attributes = { "http.request.method": "GET", "url.scheme": "http", + "http.route": "/hello/", "network.protocol.version": "1.1", "http.response.status_code": 200, } From 910d5ec2810294b79e5686af1a13862acc2609d5 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 22 Jul 2024 12:02:35 -0700 Subject: [PATCH 108/335] HTTP semantic convention stability migration for django (#2714) --- CHANGELOG.md | 6 +- .../aiohttp_server/__init__.py | 2 +- .../instrumentation/django/__init__.py | 49 ++- .../django/middleware/otel_middleware.py | 134 ++++--- .../tests/test_middleware.py | 343 +++++++++++++++++- .../tests/test_middleware_asgi.py | 267 +++++++++++++- .../instrumentation/falcon/__init__.py | 2 +- .../instrumentation/pyramid/callbacks.py | 2 +- .../instrumentation/tornado/__init__.py | 2 +- 9 files changed, 736 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ed29f8ad3..a320a1d4fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2673)) - `opentelemetry-instrumentation-django` Add `http.target` to Django duration metric attributes ([#2624](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2624)) +- `opentelemetry-instrumentation-django` Implement new semantic convention opt-in with stable http semantic conventions + ([#2714](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2714)) ### Breaking changes @@ -46,8 +48,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580)) - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `asgi` middleware ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) - - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `fastapi` middleware +- Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `fastapi` instrumentation ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) +- Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `django` middleware + ([#2714](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2714)) ### Fixed - Handle `redis.exceptions.WatchError` as a non-error event in redis instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py index 2e519ac1c5..659ff24af6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py @@ -207,7 +207,7 @@ async def middleware(request, handler): duration_histogram = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP client requests.", + description="Duration of HTTP server requests.", ) active_requests_counter = meter.create_up_down_counter( diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py index 37ac760283..651df12043 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py @@ -243,6 +243,13 @@ def response_hook(span, request, response): from django.conf import settings from django.core.exceptions import ImproperlyConfigured +from opentelemetry.instrumentation._semconv import ( + _get_schema_url, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _report_old, +) from opentelemetry.instrumentation.django.environment_variables import ( OTEL_PYTHON_DJANGO_INSTRUMENT, ) @@ -253,7 +260,13 @@ def response_hook(span, request, response): from opentelemetry.instrumentation.django.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.metrics import get_meter +from opentelemetry.semconv._incubating.metrics.http_metrics import ( + create_http_server_active_requests, +) from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.trace import get_tracer from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls @@ -293,6 +306,12 @@ def _instrument(self, **kwargs): if environ.get(OTEL_PYTHON_DJANGO_INSTRUMENT) == "False": return + # initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + tracer_provider = kwargs.get("tracer_provider") meter_provider = kwargs.get("meter_provider") _excluded_urls = kwargs.get("excluded_urls") @@ -300,14 +319,15 @@ def _instrument(self, **kwargs): __name__, __version__, tracer_provider=tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) meter = get_meter( __name__, __version__, meter_provider=meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(sem_conv_opt_in_mode), ) + _DjangoMiddleware._sem_conv_opt_in_mode = sem_conv_opt_in_mode _DjangoMiddleware._tracer = tracer _DjangoMiddleware._meter = meter _DjangoMiddleware._excluded_urls = ( @@ -319,15 +339,22 @@ def _instrument(self, **kwargs): _DjangoMiddleware._otel_response_hook = kwargs.pop( "response_hook", None ) - _DjangoMiddleware._duration_histogram = meter.create_histogram( - name=MetricInstruments.HTTP_SERVER_DURATION, - unit="ms", - description="Duration of HTTP client requests.", - ) - _DjangoMiddleware._active_request_counter = meter.create_up_down_counter( - name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, - unit="requests", - description="measures the number of concurrent HTTP requests those are currently in flight", + _DjangoMiddleware._duration_histogram_old = None + if _report_old(sem_conv_opt_in_mode): + _DjangoMiddleware._duration_histogram_old = meter.create_histogram( + name=MetricInstruments.HTTP_SERVER_DURATION, + unit="ms", + description="Duration of HTTP server requests.", + ) + _DjangoMiddleware._duration_histogram_new = None + if _report_new(sem_conv_opt_in_mode): + _DjangoMiddleware._duration_histogram_new = meter.create_histogram( + name=HTTP_SERVER_REQUEST_DURATION, + description="Duration of HTTP server requests.", + unit="s", + ) + _DjangoMiddleware._active_request_counter = ( + create_http_server_active_requests(meter) ) # This can not be solved, but is an inherent problem of this approach: # the order of middleware entries matters, and here you have no control diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 11e92c9757..4530a16506 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -22,6 +22,17 @@ from django.http import HttpRequest, HttpResponse from opentelemetry.context import detach +from opentelemetry.instrumentation._semconv import ( + _filter_semconv_active_request_count_attr, + _filter_semconv_duration_attrs, + _HTTPStabilityMode, + _report_new, + _report_old, + _server_active_requests_count_attrs_new, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new, + _server_duration_attrs_old, +) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, ) @@ -40,6 +51,7 @@ collect_request_attributes as wsgi_collect_request_attributes, ) from opentelemetry.instrumentation.wsgi import wsgi_getter +from opentelemetry.semconv.attributes.http_attributes import HTTP_ROUTE from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import Span, SpanKind, use_span from opentelemetry.util.http import ( @@ -47,13 +59,12 @@ OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, SanitizeValue, - _parse_active_request_count_attrs, - _parse_duration_attrs, get_custom_headers, get_excluded_urls, get_traced_request_attrs, normalise_request_header_name, normalise_response_header_name, + sanitize_method, ) try: @@ -113,26 +124,6 @@ def __call__(self, request): _is_asgi_supported = False _logger = getLogger(__name__) -_attributes_by_preference = [ - [ - SpanAttributes.HTTP_SCHEME, - SpanAttributes.HTTP_HOST, - SpanAttributes.HTTP_TARGET, - ], - [ - SpanAttributes.HTTP_SCHEME, - SpanAttributes.HTTP_SERVER_NAME, - SpanAttributes.NET_HOST_PORT, - SpanAttributes.HTTP_TARGET, - ], - [ - SpanAttributes.HTTP_SCHEME, - SpanAttributes.NET_HOST_NAME, - SpanAttributes.NET_HOST_PORT, - SpanAttributes.HTTP_TARGET, - ], - [SpanAttributes.HTTP_URL], -] def _is_asgi_request(request: HttpRequest) -> bool: @@ -159,8 +150,10 @@ class _DjangoMiddleware(MiddlewareMixin): _excluded_urls = get_excluded_urls("DJANGO") _tracer = None _meter = None - _duration_histogram = None + _duration_histogram_old = None + _duration_histogram_new = None _active_request_counter = None + _sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT _otel_request_hook: Callable[[Span, HttpRequest], None] = None _otel_response_hook: Callable[[Span, HttpRequest, HttpResponse], None] = ( @@ -169,6 +162,9 @@ class _DjangoMiddleware(MiddlewareMixin): @staticmethod def _get_span_name(request): + method = sanitize_method(request.method.strip()) + if method == "_OTHER": + return "HTTP" try: if getattr(request, "resolver_match"): match = request.resolver_match @@ -176,10 +172,10 @@ def _get_span_name(request): match = resolve(request.path) if hasattr(match, "route") and match.route: - return f"{request.method} {match.route}" + return f"{method} {match.route}" if hasattr(match, "url_name") and match.url_name: - return f"{request.method} {match.url_name}" + return f"{method} {match.url_name}" return request.method @@ -213,7 +209,10 @@ def process_request(self, request): carrier_getter = wsgi_getter collect_request_attributes = wsgi_collect_request_attributes - attributes = collect_request_attributes(carrier) + attributes = collect_request_attributes( + carrier, + self._sem_conv_opt_in_mode, + ) span, token = _start_internal_or_server_span( tracer=self._tracer, span_name=self._get_span_name(request), @@ -226,14 +225,15 @@ def process_request(self, request): ) active_requests_count_attrs = _parse_active_request_count_attrs( - attributes + attributes, + self._sem_conv_opt_in_mode, ) - duration_attrs = _parse_duration_attrs(attributes) request.META[self._environ_active_request_attr_key] = ( active_requests_count_attrs ) - request.META[self._environ_duration_attr_key] = duration_attrs + # Pass all of attributes to duration key because we will filter during response + request.META[self._environ_duration_attr_key] = attributes self._active_request_counter.add(1, active_requests_count_attrs) if span.is_recording(): attributes = extract_attributes_from_object( @@ -309,18 +309,20 @@ def process_view(self, request, view_func, *args, **kwargs): ): span = request.META[self._environ_span_key] - if span.is_recording(): - match = getattr(request, "resolver_match", None) - if match: - route = getattr(match, "route", None) - if route: + match = getattr(request, "resolver_match", None) + if match: + route = getattr(match, "route", None) + if route: + if span.is_recording(): + # http.route is present for both old and new semconv span.set_attribute(SpanAttributes.HTTP_ROUTE, route) - duration_attrs = request.META[ - self._environ_duration_attr_key - ] - # Metrics currently use the 1.11.0 schema, which puts the route in `http.target`. - # TODO: use `http.route` when the user sets `OTEL_SEMCONV_STABILITY_OPT_IN`. + duration_attrs = request.META[ + self._environ_duration_attr_key + ] + if _report_old(self._sem_conv_opt_in_mode): duration_attrs[SpanAttributes.HTTP_TARGET] = route + if _report_new(self._sem_conv_opt_in_mode): + duration_attrs[HTTP_ROUTE] = route def process_exception(self, request, exception): if self._excluded_urls.url_disabled(request.build_absolute_uri("?")): @@ -347,15 +349,16 @@ def process_response(self, request, response): duration_attrs = request.META.pop( self._environ_duration_attr_key, None ) - if duration_attrs: - duration_attrs[SpanAttributes.HTTP_STATUS_CODE] = ( - response.status_code - ) request_start_time = request.META.pop(self._environ_timer_key, None) if activation and span: if is_asgi_request: - set_status_code(span, response.status_code) + set_status_code( + span, + response.status_code, + metric_attributes=duration_attrs, + sem_conv_opt_in_mode=self._sem_conv_opt_in_mode, + ) if span.is_recording() and span.kind == SpanKind.SERVER: custom_headers = {} @@ -381,6 +384,8 @@ def process_response(self, request, response): span, f"{response.status_code} {response.reason_phrase}", response.items(), + duration_attrs=duration_attrs, + sem_conv_opt_in_mode=self._sem_conv_opt_in_mode, ) if span.is_recording() and span.kind == SpanKind.SERVER: custom_attributes = ( @@ -416,13 +421,46 @@ def process_response(self, request, response): activation.__exit__(None, None, None) if request_start_time is not None: - duration = max( - round((default_timer() - request_start_time) * 1000), 0 - ) - self._duration_histogram.record(duration, duration_attrs) + duration_s = default_timer() - request_start_time + if self._duration_histogram_old: + duration_attrs_old = _parse_duration_attrs( + duration_attrs, _HTTPStabilityMode.DEFAULT + ) + self._duration_histogram_old.record( + max(round(duration_s * 1000), 0), duration_attrs_old + ) + if self._duration_histogram_new: + duration_attrs_new = _parse_duration_attrs( + duration_attrs, _HTTPStabilityMode.HTTP + ) + self._duration_histogram_new.record( + max(duration_s, 0), duration_attrs_new + ) self._active_request_counter.add(-1, active_requests_count_attrs) if request.META.get(self._environ_token, None) is not None: detach(request.META.get(self._environ_token)) request.META.pop(self._environ_token) return response + + +def _parse_duration_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_duration_attrs( + req_attrs, + _server_duration_attrs_old, + _server_duration_attrs_new, + sem_conv_opt_in_mode, + ) + + +def _parse_active_request_count_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_active_request_count_attr( + req_attrs, + _server_active_requests_count_attrs_old, + _server_active_requests_count_attrs_new, + sem_conv_opt_in_mode, + ) diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index 4945f05455..1b9a904ce1 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -13,6 +13,7 @@ # limitations under the License. # pylint: disable=E0611 +# pylint: disable=too-many-lines from sys import modules from timeit import default_timer @@ -24,6 +25,14 @@ from django.test.utils import setup_test_environment, teardown_test_environment from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, + _server_active_requests_count_attrs_new, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new, + _server_duration_attrs_old, +) from opentelemetry.instrumentation.django import ( DjangoInstrumentor, _DjangoMiddleware, @@ -39,6 +48,23 @@ ) from opentelemetry.sdk.trace import Span from opentelemetry.sdk.trace.id_generator import RandomIdGenerator +from opentelemetry.semconv.attributes.client_attributes import CLIENT_ADDRESS +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.exception_attributes import ( + EXCEPTION_MESSAGE, + EXCEPTION_TYPE, +) +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import SERVER_PORT +from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.trace import ( @@ -51,8 +77,6 @@ OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, - _active_requests_count_attrs, - _duration_attrs, get_excluded_urls, get_traced_request_attrs, ) @@ -112,15 +136,25 @@ def setUpClass(cls): def setUp(self): super().setUp() setup_test_environment() - _django_instrumentor.instrument() + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" self.env_patch = patch.dict( "os.environ", { "OTEL_PYTHON_DJANGO_EXCLUDED_URLS": "http://testserver/excluded_arg/123,excluded_noarg", "OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS": "path_info,content_type,non_existing_variable", + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) + _OpenTelemetrySemanticConventionStability._initialized = False self.env_patch.start() + _django_instrumentor.instrument() self.exclude_patch = patch( "opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware._excluded_urls", get_excluded_urls("DJANGO"), @@ -199,6 +233,57 @@ def test_traced_get(self): self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + def test_traced_get_new_semconv(self): + Client().get("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + if DJANGO_2_2: + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + + def test_traced_get_both_semconv(self): + Client().get("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://testserver/traced/", + ) + if DJANGO_2_2: + self.assertEqual( + span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/" + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + if DJANGO_2_2: + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + def test_not_recording(self): mock_tracer = Mock() mock_span = Mock() @@ -245,6 +330,53 @@ def test_traced_post(self): self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + def test_traced_post_new_semconv(self): + Client().post("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + if DJANGO_2_2: + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + + def test_traced_post_both_semconv(self): + Client().post("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "POST") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://testserver/traced/", + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + if DJANGO_2_2: + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + def test_error(self): with self.assertRaises(ValueError): Client().get("/error/") @@ -279,6 +411,67 @@ def test_error(self): event.attributes[SpanAttributes.EXCEPTION_MESSAGE], "error" ) + def test_error_new_semconv(self): + with self.assertRaises(ValueError): + Client().get("/error/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + if DJANGO_2_2: + self.assertEqual(span.attributes[HTTP_ROUTE], "^error/") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500) + + self.assertEqual(len(span.events), 1) + event = span.events[0] + self.assertEqual(event.name, "exception") + self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError") + self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error") + self.assertEqual(span.attributes[ERROR_TYPE], "500") + + def test_error_both_semconv(self): + with self.assertRaises(ValueError): + Client().get("/error/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://testserver/error/", + ) + if DJANGO_2_2: + self.assertEqual( + span.attributes[SpanAttributes.HTTP_ROUTE], "^error/" + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + if DJANGO_2_2: + self.assertEqual(span.attributes[HTTP_ROUTE], "^error/") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500) + + self.assertEqual(len(span.events), 1) + event = span.events[0] + self.assertEqual(event.name, "exception") + self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError") + self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error") + self.assertEqual(span.attributes[ERROR_TYPE], "500") + def test_exclude_lists(self): client = Client() client.get("/excluded_arg/123") @@ -343,6 +536,46 @@ def test_span_name_404(self): span = span_list[0] self.assertEqual(span.name, "GET") + def test_nonstandard_http_method_span_name(self): + Client().request( + REQUEST_METHOD="NONSTANDARD", PATH_INFO="/span_name/1234/" + ) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 1) + + span = span_list[0] + self.assertEqual(span.name, "HTTP") + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER") + + def test_nonstandard_http_method_span_name_new_semconv(self): + Client().request( + REQUEST_METHOD="NONSTANDARD", PATH_INFO="/span_name/1234/" + ) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 1) + + span = span_list[0] + self.assertEqual(span.name, "HTTP") + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER") + self.assertEqual( + span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD" + ) + + def test_nonstandard_http_method_span_name_both_semconv(self): + Client().request( + REQUEST_METHOD="NONSTANDARD", PATH_INFO="/span_name/1234/" + ) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 1) + + span = span_list[0] + self.assertEqual(span.name, "HTTP") + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER") + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER") + self.assertEqual( + span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD" + ) + def test_traced_request_attrs(self): Client().get("/span_name/1234/", CONTENT_TYPE="test/ct") span_list = self.memory_exporter.get_finished_spans() @@ -479,9 +712,8 @@ def test_wsgi_metrics(self): "http.server.duration", ] _recommended_attrs = { - "http.server.active_requests": _active_requests_count_attrs, - "http.server.duration": _duration_attrs - | {SpanAttributes.HTTP_TARGET}, + "http.server.active_requests": _server_active_requests_count_attrs_old, + "http.server.duration": _server_duration_attrs_old, } start = default_timer() for _ in range(3): @@ -517,6 +749,105 @@ def test_wsgi_metrics(self): ) self.assertTrue(histrogram_data_point_seen and number_data_point_seen) + # pylint: disable=too-many-locals + def test_wsgi_metrics_new_semconv(self): + _expected_metric_names = [ + "http.server.active_requests", + "http.server.request.duration", + ] + _recommended_attrs = { + "http.server.active_requests": _server_active_requests_count_attrs_new, + "http.server.request.duration": _server_duration_attrs_new, + } + start = default_timer() + for _ in range(3): + response = Client().get("/span_name/1234/") + self.assertEqual(response.status_code, 200) + duration_s = default_timer() - start + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histrogram_data_point_seen = False + + self.assertTrue(len(metrics_list.resource_metrics) != 0) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) != 0) + for scope_metric in resource_metric.scope_metrics: + self.assertTrue(len(scope_metric.metrics) != 0) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histrogram_data_point_seen = True + self.assertAlmostEqual( + duration_s, point.sum, places=1 + ) + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + self.assertEqual(point.value, 0) + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs[metric.name] + ) + self.assertTrue(histrogram_data_point_seen and number_data_point_seen) + + # pylint: disable=too-many-locals + # pylint: disable=too-many-nested-blocks + def test_wsgi_metrics_both_semconv(self): + _expected_metric_names = [ + "http.server.duration", + "http.server.active_requests", + "http.server.request.duration", + ] + active_count_both_attrs = list(_server_active_requests_count_attrs_new) + active_count_both_attrs.extend(_server_active_requests_count_attrs_old) + _recommended_attrs = { + "http.server.active_requests": active_count_both_attrs, + "http.server.request.duration": _server_duration_attrs_new, + "http.server.duration": _server_duration_attrs_old, + } + start = default_timer() + for _ in range(3): + response = Client().get("/span_name/1234/") + self.assertEqual(response.status_code, 200) + duration_s = max(default_timer() - start, 0) + duration = max(round(duration_s * 1000), 0) + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histrogram_data_point_seen = False + + self.assertTrue(len(metrics_list.resource_metrics) != 0) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) != 0) + for scope_metric in resource_metric.scope_metrics: + self.assertTrue(len(scope_metric.metrics) != 0) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histrogram_data_point_seen = True + if metric.name == "http.server.request.duration": + self.assertAlmostEqual( + duration_s, point.sum, places=1 + ) + elif metric.name == "http.server.duration": + self.assertAlmostEqual( + duration, point.sum, delta=100 + ) + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + self.assertEqual(point.value, 0) + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs[metric.name] + ) + self.assertTrue(histrogram_data_point_seen and number_data_point_seen) + def test_wsgi_metrics_unistrument(self): Client().get("/span_name/1234/") _django_instrumentor.uninstrument() diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware_asgi.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware_asgi.py index 0e2472d15e..d06c9c635c 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware_asgi.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware_asgi.py @@ -24,6 +24,10 @@ from django.test.utils import setup_test_environment, teardown_test_environment from opentelemetry import trace as trace_api +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.django import ( DjangoInstrumentor, _DjangoMiddleware, @@ -35,6 +39,22 @@ from opentelemetry.sdk import resources from opentelemetry.sdk.trace import Span from opentelemetry.sdk.trace.id_generator import RandomIdGenerator +from opentelemetry.semconv.attributes.client_attributes import CLIENT_ADDRESS +from opentelemetry.semconv.attributes.exception_attributes import ( + EXCEPTION_MESSAGE, + EXCEPTION_TYPE, +) +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import SERVER_PORT +from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.trace import ( @@ -87,6 +107,7 @@ @pytest.mark.skipif( not DJANGO_3_1, reason="AsyncClient implemented since Django 3.1" ) +# pylint: disable=too-many-public-methods class TestMiddlewareAsgi(SimpleTestCase, TestBase): @classmethod def setUpClass(cls): @@ -96,15 +117,25 @@ def setUpClass(cls): def setUp(self): super().setUp() setup_test_environment() - _django_instrumentor.instrument() + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" self.env_patch = patch.dict( "os.environ", { "OTEL_PYTHON_DJANGO_EXCLUDED_URLS": "http://testserver/excluded_arg/123,excluded_noarg", "OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS": "path_info,content_type,non_existing_variable", + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) + _OpenTelemetrySemanticConventionStability._initialized = False self.env_patch.start() + _django_instrumentor.instrument() self.exclude_patch = patch( "opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware._excluded_urls", get_excluded_urls("DJANGO"), @@ -152,6 +183,57 @@ async def test_templated_route_get(self): self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + async def test_templated_route_get_new_semconv(self): + await self.async_client.get("/route/2020/template/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^route/(?P[0-9]{4})/template/$") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual( + span.attributes[HTTP_ROUTE], + "^route/(?P[0-9]{4})/template/$", + ) + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + + async def test_templated_route_get_both_semconv(self): + await self.async_client.get("/route/2020/template/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^route/(?P[0-9]{4})/template/$") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://127.0.0.1/route/2020/template/", + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual( + span.attributes[HTTP_ROUTE], + "^route/(?P[0-9]{4})/template/$", + ) + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + async def test_traced_get(self): await self.async_client.get("/traced/") @@ -174,6 +256,51 @@ async def test_traced_get(self): self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + async def test_traced_get_new_semconv(self): + await self.async_client.get("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^traced/") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + + async def test_traced_get_both_semconv(self): + await self.async_client.get("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^traced/") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://127.0.0.1/traced/", + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + async def test_not_recording(self): mock_tracer = Mock() mock_span = Mock() @@ -209,6 +336,51 @@ async def test_traced_post(self): self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + async def test_traced_post_new_semconv(self): + await self.async_client.post("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "POST ^traced/") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + + async def test_traced_post_both_semconv(self): + await self.async_client.post("/traced/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "POST ^traced/") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "POST") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://127.0.0.1/traced/", + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[SERVER_PORT], 80) + self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") + self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + async def test_error(self): with self.assertRaises(ValueError): await self.async_client.get("/error/") @@ -240,6 +412,60 @@ async def test_error(self): event.attributes[SpanAttributes.EXCEPTION_MESSAGE], "error" ) + async def test_error_new_semconv(self): + with self.assertRaises(ValueError): + await self.async_client.get("/error/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^error/") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[HTTP_ROUTE], "^error/") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500) + + self.assertEqual(len(span.events), 1) + event = span.events[0] + self.assertEqual(event.name, "exception") + self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError") + self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error") + + async def test_error_both_semconv(self): + with self.assertRaises(ValueError): + await self.async_client.get("/error/") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + + self.assertEqual(span.name, "GET ^error/") + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual( + span.attributes[SpanAttributes.HTTP_URL], + "http://127.0.0.1/error/", + ) + self.assertEqual(span.attributes[SpanAttributes.HTTP_ROUTE], "^error/") + self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") + self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500) + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes[HTTP_ROUTE], "^error/") + self.assertEqual(span.attributes[URL_SCHEME], "http") + self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500) + + self.assertEqual(len(span.events), 1) + event = span.events[0] + self.assertEqual(event.name, "exception") + self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError") + self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error") + async def test_exclude_lists(self): await self.async_client.get("/excluded_arg/123") span_list = self.memory_exporter.get_finished_spans() @@ -285,6 +511,45 @@ async def test_span_name_404(self): span = span_list[0] self.assertEqual(span.name, "GET") + async def test_nonstandard_http_method_span_name(self): + await self.async_client.request( + method="NONSTANDARD", path="/span_name/1234/" + ) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 1) + + span = span_list[0] + self.assertEqual(span.name, "HTTP") + + async def test_nonstandard_http_method_span_name_new_semconv(self): + await self.async_client.request( + method="NONSTANDARD", path="/span_name/1234/" + ) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 1) + + span = span_list[0] + self.assertEqual(span.name, "HTTP") + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER") + self.assertEqual( + span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD" + ) + + async def test_nonstandard_http_method_span_name_both_semconv(self): + await self.async_client.request( + method="NONSTANDARD", path="/span_name/1234/" + ) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 1) + + span = span_list[0] + self.assertEqual(span.name, "HTTP") + self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER") + self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER") + self.assertEqual( + span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD" + ) + async def test_traced_request_attrs(self): await self.async_client.get("/span_name/1234/", CONTENT_TYPE="test/ct") span_list = self.memory_exporter.get_finished_spans() diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 79c9a0cf0f..1a252b9a16 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -268,7 +268,7 @@ def __init__(self, *args, **kwargs): self.duration_histogram = self._otel_meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP client requests.", + description="Duration of HTTP server requests.", ) self.active_requests_counter = self._otel_meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index d0010ed8d0..09f1645384 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -141,7 +141,7 @@ def trace_tween_factory(handler, registry): duration_histogram = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP client requests.", + description="Duration of HTTP server requests.", ) active_requests_counter = meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py index be9129bda0..1b56db3876 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -296,7 +296,7 @@ def _create_server_histograms(meter) -> Dict[str, Histogram]: MetricInstruments.HTTP_SERVER_DURATION: meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP client requests.", + description="Duration of HTTP server requests.", ), MetricInstruments.HTTP_SERVER_REQUEST_SIZE: meter.create_histogram( name=MetricInstruments.HTTP_SERVER_REQUEST_SIZE, From cc52bd27299ff767fcdcdf536b418ac33f4b29dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:56:22 -0300 Subject: [PATCH 109/335] Fix http clients method attribute in case of non standard http methods (#2726) --- CHANGELOG.md | 5 +- .../aiohttp_client/__init__.py | 11 ++- .../tests/test_aiohttp_client_integration.py | 87 +++++++++++++++++++ .../instrumentation/httpx/__init__.py | 12 +-- .../tests/test_httpx_integration.py | 54 ++++++++++++ .../instrumentation/requests/__init__.py | 12 ++- .../tests/test_requests_integration.py | 43 +++++++++ 7 files changed, 209 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a320a1d4fc..4228bf1254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `django` middleware ([#2714](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2714)) +- `opentelemetry-instrumentation-httpx`, `opentelemetry-instrumentation-aiohttp-client`, + `opentelemetry-instrumentation-requests` Populate `{method}` as `HTTP` on `_OTHER` methods + ([#2726](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2726)) ### Fixed - Handle `redis.exceptions.WatchError` as a non-error event in redis instrumentation @@ -79,7 +82,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2153](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2153)) - `opentelemetry-instrumentation-asgi` Removed `NET_HOST_NAME` AND `NET_HOST_PORT` from active requests count attribute ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) -- `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. +- `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. ([#2627](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2627)) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index 459e3121b9..de60fa6379 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -132,10 +132,9 @@ def response_hook(span: Span, params: typing.Union[ def _get_span_name(method: str) -> str: - method = sanitize_method(method.upper().strip()) + method = sanitize_method(method.strip()) if method == "_OTHER": method = "HTTP" - return method @@ -230,8 +229,8 @@ async def on_request_start( trace_config_ctx.span = None return - http_method = params.method - request_span_name = _get_span_name(http_method) + method = params.method + request_span_name = _get_span_name(method) request_url = ( remove_url_credentials(trace_config_ctx.url_filter(params.url)) if callable(trace_config_ctx.url_filter) @@ -241,8 +240,8 @@ async def on_request_start( span_attributes = {} _set_http_method( span_attributes, - http_method, - request_span_name, + method, + sanitize_method(method), sem_conv_opt_in_mode, ) _set_http_url(span_attributes, request_url, sem_conv_opt_in_mode) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 538421dd6a..3873a6f094 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -40,6 +40,7 @@ from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.attributes.http_attributes import ( HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, HTTP_RESPONSE_STATUS_CODE, ) from opentelemetry.semconv.attributes.url_attributes import URL_FULL @@ -503,6 +504,92 @@ async def request_handler(request): ] ) + def test_nonstandard_http_method(self): + trace_configs = [aiohttp_client.create_trace_config()] + app = HttpServerMock("nonstandard_method") + + @app.route("/status/200", methods=["NONSTANDARD"]) + def index(): + return ("", 405, {}) + + url = "http://localhost:5000/status/200" + + with app.run("localhost", 5000): + with self.subTest(url=url): + + async def do_request(url): + async with aiohttp.ClientSession( + trace_configs=trace_configs, + ) as session: + async with session.request("NONSTANDARD", url): + pass + + loop = asyncio.get_event_loop() + loop.run_until_complete(do_request(url)) + + self.assert_spans( + [ + ( + "HTTP", + (StatusCode.ERROR, None), + { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_URL: url, + SpanAttributes.HTTP_STATUS_CODE: int( + HTTPStatus.METHOD_NOT_ALLOWED + ), + }, + ) + ] + ) + self.memory_exporter.clear() + + def test_nonstandard_http_method_new_semconv(self): + trace_configs = [ + aiohttp_client.create_trace_config( + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + ) + ] + app = HttpServerMock("nonstandard_method") + + @app.route("/status/200", methods=["NONSTANDARD"]) + def index(): + return ("", 405, {}) + + url = "http://localhost:5000/status/200" + + with app.run("localhost", 5000): + with self.subTest(url=url): + + async def do_request(url): + async with aiohttp.ClientSession( + trace_configs=trace_configs, + ) as session: + async with session.request("NONSTANDARD", url): + pass + + loop = asyncio.get_event_loop() + loop.run_until_complete(do_request(url)) + + self.assert_spans( + [ + ( + "HTTP", + (StatusCode.ERROR, None), + { + HTTP_REQUEST_METHOD: "_OTHER", + URL_FULL: url, + HTTP_RESPONSE_STATUS_CODE: int( + HTTPStatus.METHOD_NOT_ALLOWED + ), + HTTP_REQUEST_METHOD_ORIGINAL: "NONSTANDARD", + ERROR_TYPE: "405", + }, + ) + ] + ) + self.memory_exporter.clear() + def test_credential_removal(self): trace_configs = [aiohttp_client.create_trace_config()] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index e3ce383d7e..f2a18a2770 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -259,7 +259,7 @@ class ResponseInfo(typing.NamedTuple): def _get_default_span_name(method: str) -> str: - method = sanitize_method(method.upper().strip()) + method = sanitize_method(method.strip()) if method == "_OTHER": method = "HTTP" @@ -326,12 +326,16 @@ def _apply_request_client_attributes_to_span( span_attributes: dict, url: typing.Union[str, URL, httpx.URL], method_original: str, - span_name: str, semconv: _HTTPStabilityMode, ): url = httpx.URL(url) # http semconv transition: http.method -> http.request.method - _set_http_method(span_attributes, method_original, span_name, semconv) + _set_http_method( + span_attributes, + method_original, + sanitize_method(method_original), + semconv, + ) # http semconv transition: http.url -> url.full _set_http_url(span_attributes, str(url), semconv) @@ -450,7 +454,6 @@ def handle_request( span_attributes, url, method_original, - span_name, self._sem_conv_opt_in_mode, ) @@ -572,7 +575,6 @@ async def handle_async_request(self, *args, **kwargs) -> typing.Union[ span_attributes, url, method_original, - span_name, self._sem_conv_opt_in_mode, ) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 03141e61b5..011b5e57d2 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -39,6 +39,7 @@ from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.attributes.http_attributes import ( HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, HTTP_RESPONSE_STATUS_CODE, ) from opentelemetry.semconv.attributes.network_attributes import ( @@ -217,6 +218,59 @@ def test_basic(self): span, opentelemetry.instrumentation.httpx ) + def test_nonstandard_http_method(self): + respx.route(method="NONSTANDARD").mock( + return_value=httpx.Response(405) + ) + self.perform_request(self.URL, method="NONSTANDARD") + span = self.assert_span() + + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "HTTP") + self.assertEqual( + span.attributes, + { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_URL: self.URL, + SpanAttributes.HTTP_STATUS_CODE: 405, + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.ERROR) + + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.httpx + ) + + def test_nonstandard_http_method_new_semconv(self): + respx.route(method="NONSTANDARD").mock( + return_value=httpx.Response(405) + ) + self.perform_request(self.URL, method="NONSTANDARD") + span = self.assert_span() + + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "HTTP") + self.assertEqual( + span.attributes, + { + HTTP_REQUEST_METHOD: "_OTHER", + URL_FULL: self.URL, + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + HTTP_RESPONSE_STATUS_CODE: 405, + NETWORK_PROTOCOL_VERSION: "1.1", + ERROR_TYPE: "405", + HTTP_REQUEST_METHOD_ORIGINAL: "NONSTANDARD", + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.ERROR) + + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.httpx + ) + def test_basic_new_semconv(self): url = "http://mock:8080/status/200" respx.get(url).mock( diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 0a55564386..3aa1b476f5 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -188,13 +188,19 @@ def get_or_create_headers(): span_attributes = {} _set_http_method( - span_attributes, method, span_name, sem_conv_opt_in_mode + span_attributes, + method, + sanitize_method(method), + sem_conv_opt_in_mode, ) _set_http_url(span_attributes, url, sem_conv_opt_in_mode) metric_labels = {} _set_http_method( - metric_labels, method, span_name, sem_conv_opt_in_mode + metric_labels, + method, + sanitize_method(method), + sem_conv_opt_in_mode, ) try: @@ -365,7 +371,7 @@ def get_default_span_name(method): Returns: span name """ - method = sanitize_method(method.upper().strip()) + method = sanitize_method(method.strip()) if method == "_OTHER": return "HTTP" return method diff --git a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py index 75518fc8d3..a5cb8927ae 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py +++ b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py @@ -36,6 +36,7 @@ from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.attributes.http_attributes import ( HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, HTTP_RESPONSE_STATUS_CODE, ) from opentelemetry.semconv.attributes.network_attributes import ( @@ -247,6 +248,48 @@ def test_basic_both_semconv(self): span, opentelemetry.instrumentation.requests ) + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_nonstandard_http_method(self): + httpretty.register_uri("NONSTANDARD", self.URL, status=405) + session = requests.Session() + session.request("NONSTANDARD", self.URL) + span = self.assert_span() + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "HTTP") + self.assertEqual( + span.attributes, + { + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_URL: self.URL, + SpanAttributes.HTTP_STATUS_CODE: 405, + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.ERROR) + + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_nonstandard_http_method_new_semconv(self): + httpretty.register_uri("NONSTANDARD", self.URL, status=405) + session = requests.Session() + session.request("NONSTANDARD", self.URL) + span = self.assert_span() + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "HTTP") + self.assertEqual( + span.attributes, + { + HTTP_REQUEST_METHOD: "_OTHER", + URL_FULL: self.URL, + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + HTTP_RESPONSE_STATUS_CODE: 405, + NETWORK_PROTOCOL_VERSION: "1.1", + ERROR_TYPE: "405", + HTTP_REQUEST_METHOD_ORIGINAL: "NONSTANDARD", + }, + ) + self.assertIs(span.status.status_code, trace.StatusCode.ERROR) + def test_hooks(self): def request_hook(span, request_obj): span.update_name("name set from hook") From 948b47d43c750c703b5b36d04e3d55b110ca9dac Mon Sep 17 00:00:00 2001 From: CC Date: Tue, 23 Jul 2024 21:24:01 +0530 Subject: [PATCH 110/335] Add NoOpTraceProvider test for opentelemetry-instrumentation-logging (#2649) --- .../tests/test_logging.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py index a5a0d5adff..c8b8744cf3 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py +++ b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py @@ -23,7 +23,7 @@ LoggingInstrumentor, ) from opentelemetry.test.test_base import TestBase -from opentelemetry.trace import ProxyTracer, get_tracer +from opentelemetry.trace import NoOpTracerProvider, ProxyTracer, get_tracer class FakeTracerProvider: @@ -207,3 +207,18 @@ def test_uninstrumented(self): self.assertFalse(hasattr(record, "otelTraceID")) self.assertFalse(hasattr(record, "otelServiceName")) self.assertFalse(hasattr(record, "otelTraceSampled")) + + def test_no_op_tracer_provider(self): + LoggingInstrumentor().uninstrument() + LoggingInstrumentor().instrument(tracer_provider=NoOpTracerProvider()) + + with self.caplog.at_level(level=logging.INFO): + logger = logging.getLogger("test logger") + logger.info("hello") + + self.assertEqual(len(self.caplog.records), 1) + record = self.caplog.records[0] + self.assertEqual(record.otelSpanID, "0") + self.assertEqual(record.otelTraceID, "0") + self.assertEqual(record.otelServiceName, "") + self.assertEqual(record.otelTraceSampled, False) From 38e4ea4a2400e8560c36f2fcdf1c61987fb4ebf8 Mon Sep 17 00:00:00 2001 From: Zhihan Li <54661071+zhihali@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:31:33 +0100 Subject: [PATCH 111/335] Teach fastapi instrumentation about fastapi-slim (#2702) --- .github/workflows/instrumentations_1.yml | 1 + CHANGELOG.md | 3 ++ instrumentation/README.md | 2 +- .../pyproject.toml | 3 +- .../instrumentation/fastapi/__init__.py | 12 ++++++- .../instrumentation/fastapi/package.py | 5 ++- .../test-requirements-slim.txt | 32 +++++++++++++++++++ .../instrumentation/bootstrap_gen.py | 4 +++ tox.ini | 7 ++++ 9 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 8c99eb0572..a658796ef8 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -38,6 +38,7 @@ jobs: - "resource-detector-azure" - "resource-detector-container" - "util-http" + - "fastapi-slim" os: [ubuntu-20.04] exclude: - python-version: pypy3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4228bf1254..7caff5e940 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,8 +55,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx`, `opentelemetry-instrumentation-aiohttp-client`, `opentelemetry-instrumentation-requests` Populate `{method}` as `HTTP` on `_OTHER` methods ([#2726](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2726)) +- `opentelemetry-instrumentation-fastapi` Add dependency support for fastapi-slim + ([#2702](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2702)) ### Fixed + - Handle `redis.exceptions.WatchError` as a non-error event in redis instrumentation ([#2668](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2668)) - `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented diff --git a/instrumentation/README.md b/instrumentation/README.md index 989ba529cb..900ee6ea74 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -19,7 +19,7 @@ | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental | [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 4.0.0 | Yes | experimental -| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | migration +| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58,fastapi-slim ~= 0.111.0 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental | [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 7bae75494e..1ef5507504 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -34,7 +34,8 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "fastapi ~= 0.58", + "fastapi ~= 0.58", + "fastapi-slim ~= 0.111.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 2f9bbe7314..9356093a45 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -172,6 +172,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A --- """ import logging +from importlib.util import find_spec from typing import Collection import fastapi @@ -189,7 +190,11 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A ClientResponseHook, ServerRequestHook, ) -from opentelemetry.instrumentation.fastapi.package import _instruments +from opentelemetry.instrumentation.fastapi.package import ( + _fastapi, + _fastapi_slim, + _instruments, +) from opentelemetry.instrumentation.fastapi.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.metrics import get_meter @@ -280,6 +285,11 @@ def uninstrument_app(app: fastapi.FastAPI): app._is_instrumented_by_opentelemetry = False def instrumentation_dependencies(self) -> Collection[str]: + if find_spec("fastapi") is not None: + return (_fastapi,) + if find_spec("fastapi_slim") is not None: + return (_fastapi_slim,) + # If neither is installed, return both as potential dependencies return _instruments def _instrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py index d95a2cf6d5..55e1059d7a 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py @@ -13,7 +13,10 @@ # limitations under the License. -_instruments = ("fastapi ~= 0.58",) +_fastapi = "fastapi ~= 0.58" +_fastapi_slim = "fastapi-slim ~= 0.111.0" + +_instruments = (_fastapi, _fastapi_slim) _supports_metrics = True diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt new file mode 100644 index 0000000000..2ea55f1b91 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt @@ -0,0 +1,32 @@ +annotated-types==0.6.0 +anyio==4.3.0 +asgiref==3.7.2 +certifi==2024.7.4 +charset-normalizer==3.3.2 +Deprecated==1.2.14 +exceptiongroup==1.2.0 +fastapi-slim==0.111.0 +h11==0.14.0 +httpcore==1.0.4 +httpx==0.27.0 +idna==3.7 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pydantic==2.6.2 +pydantic_core==2.16.3 +pytest==7.4.4 +requests==2.32.3 +sniffio==1.3.0 +starlette==0.37.2 +tomli==2.0.1 +typing_extensions==4.9.0 +urllib3==2.2.2 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-asgi +-e util/opentelemetry-util-http +-e instrumentation/opentelemetry-instrumentation-fastapi diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 3f4c78862f..9b71a8bdff 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -84,6 +84,10 @@ "library": "fastapi ~= 0.58", "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0.dev", }, + { + "library": "fastapi-slim ~= 0.111.0", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0.dev", + }, { "library": "flask >= 1.0", "instrumentation": "opentelemetry-instrumentation-flask==0.47b0.dev", diff --git a/tox.ini b/tox.ini index aac890ed7c..4ba434b29b 100644 --- a/tox.ini +++ b/tox.ini @@ -116,7 +116,9 @@ envlist = ; opentelemetry-instrumentation-fastapi py3{8,9,10,11,12}-test-instrumentation-fastapi + py3{8,9,10,11,12}-test-instrumentation-fastapi-slim pypy3-test-instrumentation-fastapi + pypy3-test-instrumentation-fastapi-slim lint-instrumentation-fastapi ; opentelemetry-instrumentation-flask @@ -544,6 +546,11 @@ commands_pre = fastapi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk fastapi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt + fastapi-slim: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + fastapi-slim: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + fastapi-slim: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + fastapi-slim: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + fastapi-slim: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt mysql: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api mysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions From 92da527977390dc55807ab2547f31f8788255e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:09:11 -0300 Subject: [PATCH 112/335] HTTP semantic convention stability migration for urllib3 (#2715) --- CHANGELOG.md | 6 + instrumentation/README.md | 2 +- .../instrumentation/urllib3/__init__.py | 313 ++++++++++++++---- .../instrumentation/urllib3/package.py | 2 + .../tests/test_urllib3_integration.py | 230 ++++++++++++- .../tests/test_urllib3_metrics.py | 305 +++++++++++++++-- 6 files changed, 748 insertions(+), 110 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7caff5e940..bc400865a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2673)) - `opentelemetry-instrumentation-django` Add `http.target` to Django duration metric attributes ([#2624](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2624)) +- `opentelemetry-instrumentation-urllib3` Implement new semantic convention opt-in migration + ([#2715](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2715)) - `opentelemetry-instrumentation-django` Implement new semantic convention opt-in with stable http semantic conventions ([#2714](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2714)) @@ -48,6 +50,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580)) - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `asgi` middleware ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) +- Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `fastapi` middleware + ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) +- `opentelemetry-instrumentation-urllib3` Populate `{method}` as `HTTP` on `_OTHER` methods for span name + ([#2715](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2715)) - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `fastapi` instrumentation ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `django` middleware diff --git a/instrumentation/README.md b/instrumentation/README.md index 900ee6ea74..555e0bcd2a 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -46,5 +46,5 @@ | [opentelemetry-instrumentation-tornado](./opentelemetry-instrumentation-tornado) | tornado >= 5.1.1 | Yes | experimental | [opentelemetry-instrumentation-tortoiseorm](./opentelemetry-instrumentation-tortoiseorm) | tortoise-orm >= 0.17.0 | No | experimental | [opentelemetry-instrumentation-urllib](./opentelemetry-instrumentation-urllib) | urllib | Yes | experimental -| [opentelemetry-instrumentation-urllib3](./opentelemetry-instrumentation-urllib3) | urllib3 >= 1.0.0, < 3.0.0 | Yes | experimental +| [opentelemetry-instrumentation-urllib3](./opentelemetry-instrumentation-urllib3) | urllib3 >= 1.0.0, < 3.0.0 | Yes | migration | [opentelemetry-instrumentation-wsgi](./opentelemetry-instrumentation-wsgi) | wsgi | Yes | migration \ No newline at end of file diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index add5db8f19..a05084725d 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -87,25 +87,49 @@ def response_hook(span, request, response): import urllib3.connectionpool import wrapt +from opentelemetry.instrumentation._semconv import ( + _client_duration_attrs_new, + _client_duration_attrs_old, + _filter_semconv_duration_attrs, + _get_schema_url, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _report_old, + _set_http_host, + _set_http_method, + _set_http_net_peer_name_client, + _set_http_network_protocol_version, + _set_http_peer_port_client, + _set_http_scheme, + _set_http_url, + _set_status, +) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.urllib3.package import _instruments from opentelemetry.instrumentation.urllib3.version import __version__ from opentelemetry.instrumentation.utils import ( - http_status_to_status_code, is_http_instrumentation_enabled, suppress_http_instrumentation, unwrap, ) from opentelemetry.metrics import Histogram, get_meter from opentelemetry.propagate import inject +from opentelemetry.semconv._incubating.metrics.http_metrics import ( + create_http_client_request_body_size, + create_http_client_response_body_size, +) from opentelemetry.semconv.metrics import MetricInstruments -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_DURATION, +) from opentelemetry.trace import Span, SpanKind, Tracer, get_tracer -from opentelemetry.trace.status import Status from opentelemetry.util.http import ( ExcludeList, get_excluded_urls, parse_excluded_urls, + sanitize_method, ) from opentelemetry.util.http.httplib import set_ip_on_next_http_connection @@ -158,12 +182,18 @@ def _instrument(self, **kwargs): ``excluded_urls``: A string containing a comma-delimited list of regexes used to exclude URLs from tracking """ + # initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + schema_url = _get_schema_url(sem_conv_opt_in_mode) tracer_provider = kwargs.get("tracer_provider") tracer = get_tracer( __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=schema_url, ) excluded_urls = kwargs.get("excluded_urls") @@ -173,30 +203,57 @@ def _instrument(self, **kwargs): __name__, __version__, meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", - ) - - duration_histogram = meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_DURATION, - unit="ms", - description="Measures the duration of outbound HTTP requests.", - ) - request_size_histogram = meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_REQUEST_SIZE, - unit="By", - description="Measures the size of HTTP request messages.", - ) - response_size_histogram = meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE, - unit="By", - description="Measures the size of HTTP response messages.", + schema_url=schema_url, ) + duration_histogram_old = None + request_size_histogram_old = None + response_size_histogram_old = None + if _report_old(sem_conv_opt_in_mode): + # http.client.duration histogram + duration_histogram_old = meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_DURATION, + unit="ms", + description="Measures the duration of the outbound HTTP request", + ) + # http.client.request.size histogram + request_size_histogram_old = meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_REQUEST_SIZE, + unit="By", + description="Measures the size of HTTP request messages.", + ) + # http.client.response.size histogram + response_size_histogram_old = meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE, + unit="By", + description="Measures the size of HTTP response messages.", + ) + duration_histogram_new = None + request_size_histogram_new = None + response_size_histogram_new = None + if _report_new(sem_conv_opt_in_mode): + # http.client.request.duration histogram + duration_histogram_new = meter.create_histogram( + name=HTTP_CLIENT_REQUEST_DURATION, + unit="s", + description="Duration of HTTP client requests.", + ) + # http.client.request.body.size histogram + request_size_histogram_new = create_http_client_request_body_size( + meter + ) + # http.client.response.body.size histogram + response_size_histogram_new = ( + create_http_client_response_body_size(meter) + ) _instrument( tracer, - duration_histogram, - request_size_histogram, - response_size_histogram, + duration_histogram_old, + duration_histogram_new, + request_size_histogram_old, + request_size_histogram_new, + response_size_histogram_old, + response_size_histogram_new, request_hook=kwargs.get("request_hook"), response_hook=kwargs.get("response_hook"), url_filter=kwargs.get("url_filter"), @@ -205,21 +262,33 @@ def _instrument(self, **kwargs): if excluded_urls is None else parse_excluded_urls(excluded_urls) ), + sem_conv_opt_in_mode=sem_conv_opt_in_mode, ) def _uninstrument(self, **kwargs): _uninstrument() +def _get_span_name(method: str) -> str: + method = sanitize_method(method.strip()) + if method == "_OTHER": + method = "HTTP" + return method + + def _instrument( tracer: Tracer, - duration_histogram: Histogram, - request_size_histogram: Histogram, - response_size_histogram: Histogram, + duration_histogram_old: Histogram, + duration_histogram_new: Histogram, + request_size_histogram_old: Histogram, + request_size_histogram_new: Histogram, + response_size_histogram_old: Histogram, + response_size_histogram_new: Histogram, request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, url_filter: _UrlFilterT = None, excluded_urls: ExcludeList = None, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ): def instrumented_urlopen(wrapped, instance, args, kwargs): if not is_http_instrumentation_enabled(): @@ -233,11 +302,16 @@ def instrumented_urlopen(wrapped, instance, args, kwargs): headers = _prepare_headers(kwargs) body = _get_url_open_arg("body", args, kwargs) - span_name = method.strip() - span_attributes = { - SpanAttributes.HTTP_METHOD: method, - SpanAttributes.HTTP_URL: url, - } + span_name = _get_span_name(method) + span_attributes = {} + + _set_http_method( + span_attributes, + method, + sanitize_method(method), + sem_conv_opt_in_mode, + ) + _set_http_url(span_attributes, url, sem_conv_opt_in_mode) with tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes @@ -245,32 +319,43 @@ def instrumented_urlopen(wrapped, instance, args, kwargs): if callable(request_hook): request_hook(span, instance, headers, body) inject(headers) - + # TODO: add error handling to also set exception `error.type` in new semconv with suppress_http_instrumentation(): start_time = default_timer() response = wrapped(*args, **kwargs) - elapsed_time = round((default_timer() - start_time) * 1000) + duration_s = default_timer() - start_time + # set http status code based on semconv + metric_attributes = {} + _set_status_code_attribute( + span, response.status, metric_attributes, sem_conv_opt_in_mode + ) - _apply_response(span, response) if callable(response_hook): response_hook(span, instance, response) request_size = _get_body_size(body) response_size = int(response.headers.get("Content-Length", 0)) - metric_attributes = _create_metric_attributes( - instance, response, method + _set_metric_attributes( + metric_attributes, + instance, + response, + method, + sem_conv_opt_in_mode, ) - duration_histogram.record( - elapsed_time, attributes=metric_attributes - ) - if request_size is not None: - request_size_histogram.record( - request_size, attributes=metric_attributes - ) - response_size_histogram.record( - response_size, attributes=metric_attributes + _record_metrics( + metric_attributes, + duration_histogram_old, + duration_histogram_new, + request_size_histogram_old, + request_size_histogram_new, + response_size_histogram_old, + response_size_histogram_new, + duration_s, + request_size, + response_size, + sem_conv_opt_in_mode, ) return response @@ -342,35 +427,133 @@ def _prepare_headers(urlopen_kwargs: typing.Dict) -> typing.Dict: return headers -def _apply_response(span: Span, response: urllib3.response.HTTPResponse): - if not span.is_recording(): - return - - span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, response.status) - span.set_status(Status(http_status_to_status_code(response.status))) +def _set_status_code_attribute( + span: Span, + status_code: int, + metric_attributes: dict = None, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, +) -> None: + + status_code_str = str(status_code) + try: + status_code = int(status_code) + except ValueError: + status_code = -1 + + if metric_attributes is None: + metric_attributes = {} + + _set_status( + span, + metric_attributes, + status_code, + status_code_str, + server_span=False, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + ) -def _create_metric_attributes( +def _set_metric_attributes( + metric_attributes: dict, instance: urllib3.connectionpool.HTTPConnectionPool, response: urllib3.response.HTTPResponse, method: str, -) -> dict: - metric_attributes = { - SpanAttributes.HTTP_METHOD: method, - SpanAttributes.HTTP_HOST: instance.host, - SpanAttributes.HTTP_SCHEME: instance.scheme, - SpanAttributes.HTTP_STATUS_CODE: response.status, - SpanAttributes.NET_PEER_NAME: instance.host, - SpanAttributes.NET_PEER_PORT: instance.port, - } + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, +) -> None: + + _set_http_host(metric_attributes, instance.host, sem_conv_opt_in_mode) + _set_http_scheme(metric_attributes, instance.scheme, sem_conv_opt_in_mode) + _set_http_method( + metric_attributes, + method, + sanitize_method(method), + sem_conv_opt_in_mode, + ) + _set_http_net_peer_name_client( + metric_attributes, instance.host, sem_conv_opt_in_mode + ) + _set_http_peer_port_client( + metric_attributes, instance.port, sem_conv_opt_in_mode + ) version = getattr(response, "version") if version: - metric_attributes[SpanAttributes.HTTP_FLAVOR] = ( - "1.1" if version == 11 else "1.0" + http_version = "1.1" if version == 11 else "1.0" + _set_http_network_protocol_version( + metric_attributes, http_version, sem_conv_opt_in_mode ) - return metric_attributes + +def _filter_attributes_semconv( + metric_attributes, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, +): + duration_attrs_old = None + duration_attrs_new = None + if _report_old(sem_conv_opt_in_mode): + duration_attrs_old = _filter_semconv_duration_attrs( + metric_attributes, + _client_duration_attrs_old, + _client_duration_attrs_new, + _HTTPStabilityMode.DEFAULT, + ) + if _report_new(sem_conv_opt_in_mode): + duration_attrs_new = _filter_semconv_duration_attrs( + metric_attributes, + _client_duration_attrs_old, + _client_duration_attrs_new, + _HTTPStabilityMode.HTTP, + ) + + return (duration_attrs_old, duration_attrs_new) + + +def _record_metrics( + metric_attributes: dict, + duration_histogram_old: Histogram, + duration_histogram_new: Histogram, + request_size_histogram_old: Histogram, + request_size_histogram_new: Histogram, + response_size_histogram_old: Histogram, + response_size_histogram_new: Histogram, + duration_s: float, + request_size: typing.Optional[int], + response_size: int, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, +): + attrs_old, attrs_new = _filter_attributes_semconv( + metric_attributes, sem_conv_opt_in_mode + ) + if duration_histogram_old: + # Default behavior is to record the duration in milliseconds + duration_histogram_old.record( + max(round(duration_s * 1000), 0), + attributes=attrs_old, + ) + + if duration_histogram_new: + # New semconv record the duration in seconds + duration_histogram_new.record( + duration_s, + attributes=attrs_new, + ) + + if request_size is not None: + if request_size_histogram_old: + request_size_histogram_old.record( + request_size, attributes=attrs_old + ) + + if request_size_histogram_new: + request_size_histogram_new.record( + request_size, attributes=attrs_new + ) + + if response_size_histogram_old: + response_size_histogram_old.record(response_size, attributes=attrs_old) + + if response_size_histogram_new: + response_size_histogram_new.record(response_size, attributes=attrs_new) def _uninstrument(): diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/package.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/package.py index 9d52db0a1f..568120c44d 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/package.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/package.py @@ -16,3 +16,5 @@ _instruments = ("urllib3 >= 1.0.0, < 3.0.0",) _supports_metrics = True + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py index 23124ea590..7dc899691f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py @@ -16,16 +16,29 @@ from unittest import mock import httpretty +import httpretty.core +import httpretty.http import urllib3 import urllib3.exceptions from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor from opentelemetry.instrumentation.utils import ( suppress_http_instrumentation, suppress_instrumentation, ) from opentelemetry.propagate import get_global_textmap, set_global_textmap +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.url_attributes import URL_FULL from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase @@ -41,12 +54,23 @@ class TestURLLib3Instrumentor(TestBase): def setUp(self): super().setUp() + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + self.env_patch = mock.patch.dict( "os.environ", { - "OTEL_PYTHON_URLLIB3_EXCLUDED_URLS": "http://localhost/env_excluded_arg/123,env_excluded_noarg" + "OTEL_PYTHON_URLLIB3_EXCLUDED_URLS": "http://localhost/env_excluded_arg/123,env_excluded_noarg", + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) + _OpenTelemetrySemanticConventionStability._initialized = False self.env_patch.start() self.exclude_patch = mock.patch( @@ -64,6 +88,7 @@ def setUp(self): def tearDown(self): super().tearDown() + self.env_patch.stop() URLLib3Instrumentor().uninstrument() httpretty.disable() @@ -81,46 +106,103 @@ def assert_span(self, exporter=None, num_spans=1): return span_list def assert_success_span( - self, response: urllib3.response.HTTPResponse, url: str + self, + response: urllib3.response.HTTPResponse, + url: str, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ): self.assertEqual(b"Hello!", response.data) span = self.assert_span() self.assertIs(trace.SpanKind.CLIENT, span.kind) self.assertEqual("GET", span.name) - - attributes = { + self.assertEqual( + span.status.status_code, trace.status.StatusCode.UNSET + ) + attr_old = { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: url, SpanAttributes.HTTP_STATUS_CODE: 200, } - self.assertEqual(attributes, span.attributes) - def assert_exception_span(self, url: str): - span = self.assert_span() + attr_new = { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url, + HTTP_RESPONSE_STATUS_CODE: 200, + } attributes = { + _HTTPStabilityMode.DEFAULT: attr_old, + _HTTPStabilityMode.HTTP: attr_new, + _HTTPStabilityMode.HTTP_DUP: {**attr_new, **attr_old}, + } + self.assertEqual(span.attributes, attributes.get(sem_conv_opt_in_mode)) + + def assert_exception_span( + self, + url: str, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + ): + span = self.assert_span() + + attr_old = { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: url, } - self.assertEqual(attributes, span.attributes) + + attr_new = { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url, + # TODO: Add `error.type` attribute when supported + } + + attributes = { + _HTTPStabilityMode.DEFAULT: attr_old, + _HTTPStabilityMode.HTTP: attr_new, + _HTTPStabilityMode.HTTP_DUP: {**attr_new, **attr_old}, + } + + self.assertEqual(span.attributes, attributes.get(sem_conv_opt_in_mode)) self.assertEqual( trace.status.StatusCode.ERROR, span.status.status_code ) @staticmethod def perform_request( - url: str, headers: typing.Mapping = None, retries: urllib3.Retry = None + url: str, + headers: typing.Mapping = None, + retries: urllib3.Retry = None, + method: str = "GET", ) -> urllib3.response.HTTPResponse: if retries is None: retries = urllib3.Retry.from_int(0) pool = urllib3.PoolManager() - return pool.request("GET", url, headers=headers, retries=retries) + return pool.request(method, url, headers=headers, retries=retries) def test_basic_http_success(self): response = self.perform_request(self.HTTP_URL) - self.assert_success_span(response, self.HTTP_URL) + self.assert_success_span( + response, + self.HTTP_URL, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + ) + + def test_basic_http_success_new_semconv(self): + response = self.perform_request(self.HTTP_URL) + self.assert_success_span( + response, + self.HTTP_URL, + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, + ) + + def test_basic_http_success_both_semconv(self): + response = self.perform_request(self.HTTP_URL) + self.assert_success_span( + response, + self.HTTP_URL, + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP, + ) def test_basic_http_success_using_connection_pool(self): pool = urllib3.HTTPConnectionPool("mock") @@ -145,10 +227,32 @@ def test_schema_url(self): self.assertEqual(b"Hello!", response.data) span = self.assert_span() self.assertEqual( - span.instrumentation_info.schema_url, + span.instrumentation_scope.schema_url, "https://opentelemetry.io/schemas/1.11.0", ) + def test_schema_url_new_semconv(self): + pool = urllib3.HTTPSConnectionPool("mock") + response = pool.request("GET", "/status/200") + + self.assertEqual(b"Hello!", response.data) + span = self.assert_span() + self.assertEqual( + span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/v1.21.0", + ) + + def test_schema_url_both_semconv(self): + pool = urllib3.HTTPSConnectionPool("mock") + response = pool.request("GET", "/status/200") + + self.assertEqual(b"Hello!", response.data) + span = self.assert_span() + self.assertEqual( + span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/v1.21.0", + ) + def test_basic_not_found(self): url_404 = "http://mock/status/404" httpretty.register_uri(httpretty.GET, url_404, status=404) @@ -162,6 +266,80 @@ def test_basic_not_found(self): ) self.assertIs(trace.status.StatusCode.ERROR, span.status.status_code) + def test_basic_not_found_new_semconv(self): + url_404 = "http://mock/status/404" + httpretty.register_uri(httpretty.GET, url_404, status=404) + + response = self.perform_request(url_404) + self.assertEqual(404, response.status) + + span = self.assert_span() + self.assertEqual(404, span.attributes.get(HTTP_RESPONSE_STATUS_CODE)) + self.assertIs(trace.status.StatusCode.ERROR, span.status.status_code) + + def test_basic_not_found_both_semconv(self): + url_404 = "http://mock/status/404" + httpretty.register_uri(httpretty.GET, url_404, status=404) + + response = self.perform_request(url_404) + self.assertEqual(404, response.status) + + span = self.assert_span() + self.assertEqual(404, span.attributes.get(HTTP_RESPONSE_STATUS_CODE)) + self.assertEqual( + 404, span.attributes.get(SpanAttributes.HTTP_STATUS_CODE) + ) + self.assertIs(trace.status.StatusCode.ERROR, span.status.status_code) + + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_nonstandard_http_method(self): + httpretty.register_uri( + "NONSTANDARD", self.HTTP_URL, body="Hello!", status=405 + ) + self.perform_request(self.HTTP_URL, method="NONSTANDARD") + span = self.assert_span() + self.assertEqual("HTTP", span.name) + self.assertEqual( + span.attributes.get(SpanAttributes.HTTP_METHOD), "_OTHER" + ) + self.assertEqual( + span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 405 + ) + + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_nonstandard_http_method_new_semconv(self): + httpretty.register_uri( + "NONSTANDARD", self.HTTP_URL, body="Hello!", status=405 + ) + self.perform_request(self.HTTP_URL, method="NONSTANDARD") + span = self.assert_span() + self.assertEqual("HTTP", span.name) + self.assertEqual(span.attributes.get(HTTP_REQUEST_METHOD), "_OTHER") + self.assertEqual( + span.attributes.get(HTTP_REQUEST_METHOD_ORIGINAL), "NONSTANDARD" + ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 405) + + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_nonstandard_http_method_both_semconv(self): + httpretty.register_uri( + "NONSTANDARD", self.HTTP_URL, body="Hello!", status=405 + ) + self.perform_request(self.HTTP_URL, method="NONSTANDARD") + span = self.assert_span() + self.assertEqual("HTTP", span.name) + self.assertEqual( + span.attributes.get(SpanAttributes.HTTP_METHOD), "_OTHER" + ) + self.assertEqual( + span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 405 + ) + self.assertEqual(span.attributes.get(HTTP_REQUEST_METHOD), "_OTHER") + self.assertEqual( + span.attributes.get(HTTP_REQUEST_METHOD_ORIGINAL), "NONSTANDARD" + ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 405) + def test_basic_http_non_default_port(self): url = "http://mock:666/status/200" httpretty.register_uri(httpretty.GET, url, body="Hello!") @@ -287,6 +465,34 @@ def test_request_exception(self, _): self.assert_exception_span(self.HTTP_URL) + @mock.patch( + "urllib3.connectionpool.HTTPConnectionPool._make_request", + side_effect=urllib3.exceptions.ConnectTimeoutError, + ) + def test_request_exception_new_semconv(self, _): + with self.assertRaises(urllib3.exceptions.ConnectTimeoutError): + self.perform_request( + self.HTTP_URL, retries=urllib3.Retry(connect=False) + ) + + self.assert_exception_span( + self.HTTP_URL, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + ) + + @mock.patch( + "urllib3.connectionpool.HTTPConnectionPool._make_request", + side_effect=urllib3.exceptions.ConnectTimeoutError, + ) + def test_request_exception_both_semconv(self, _): + with self.assertRaises(urllib3.exceptions.ConnectTimeoutError): + self.perform_request( + self.HTTP_URL, retries=urllib3.Retry(connect=False) + ) + + self.assert_exception_span( + self.HTTP_URL, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + ) + @mock.patch( "urllib3.connectionpool.HTTPConnectionPool._make_request", side_effect=urllib3.exceptions.ProtocolError, diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py index 787b920d7c..c6e9011351 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py @@ -14,13 +14,30 @@ import io from timeit import default_timer +from unittest import mock import httpretty import urllib3 import urllib3.exceptions from urllib3 import encode_multipart_formdata +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.httptest import HttpTestBase from opentelemetry.test.test_base import TestBase @@ -30,6 +47,24 @@ class TestURLLib3InstrumentorMetric(HttpTestBase, TestBase): def setUp(self): super().setUp() + + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + + self.env_patch = mock.patch.dict( + "os.environ", + { + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, + }, + ) + _OpenTelemetrySemanticConventionStability._initialized = False + self.env_patch.start() URLLib3Instrumentor().instrument() httpretty.enable(allow_net_connect=False) httpretty.register_uri(httpretty.GET, self.HTTP_URL, body="Hello!") @@ -38,6 +73,7 @@ def setUp(self): def tearDown(self): super().tearDown() + self.env_patch.stop() self.pool.clear() URLLib3Instrumentor().uninstrument() @@ -47,7 +83,149 @@ def tearDown(self): def test_basic_metrics(self): start_time = default_timer() response = self.pool.request("GET", self.HTTP_URL) - client_duration_estimated = (default_timer() - start_time) * 1000 + duration_ms = max(round((default_timer() - start_time) * 1000), 0) + metrics = self.get_sorted_metrics() + + ( + client_duration, + client_request_size, + client_response_size, + ) = metrics + + attrs_old = { + SpanAttributes.HTTP_STATUS_CODE: 200, + SpanAttributes.HTTP_HOST: "mock", + SpanAttributes.NET_PEER_PORT: 80, + SpanAttributes.NET_PEER_NAME: "mock", + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SCHEME: "http", + } + + self.assertEqual(client_duration.name, "http.client.duration") + self.assert_metric_expected( + client_duration, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=duration_ms, + max_data_point=duration_ms, + min_data_point=duration_ms, + attributes=attrs_old, + ) + ], + est_value_delta=40, + ) + + self.assertEqual(client_request_size.name, "http.client.request.size") + self.assert_metric_expected( + client_request_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=0, + max_data_point=0, + min_data_point=0, + attributes=attrs_old, + ) + ], + ) + + expected_size = len(response.data) + self.assertEqual( + client_response_size.name, "http.client.response.size" + ) + self.assert_metric_expected( + client_response_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=expected_size, + max_data_point=expected_size, + min_data_point=expected_size, + attributes=attrs_old, + ) + ], + ) + + def test_basic_metrics_new_semconv(self): + start_time = default_timer() + response = self.pool.request("GET", self.HTTP_URL) + duration_s = max(default_timer() - start_time, 0) + + metrics = self.get_sorted_metrics() + ( + client_request_size, + client_duration, + client_response_size, + ) = metrics + + attrs_new = { + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_ADDRESS: "mock", + SERVER_PORT: 80, + HTTP_REQUEST_METHOD: "GET", + HTTP_RESPONSE_STATUS_CODE: 200, + # TODO: add URL_SCHEME to tests when supported in the implementation + } + + self.assertEqual(client_duration.name, "http.client.request.duration") + self.assert_metric_expected( + client_duration, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=duration_s, + max_data_point=duration_s, + min_data_point=duration_s, + attributes=attrs_new, + ) + ], + est_value_delta=40 / 1000, + ) + + self.assertEqual( + client_request_size.name, "http.client.request.body.size" + ) + self.assert_metric_expected( + client_request_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=0, + max_data_point=0, + min_data_point=0, + attributes=attrs_new, + ) + ], + ) + + expected_size = len(response.data) + self.assertEqual( + client_response_size.name, "http.client.response.body.size" + ) + self.assert_metric_expected( + client_response_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=expected_size, + max_data_point=expected_size, + min_data_point=expected_size, + attributes=attrs_new, + ) + ], + ) + + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_basic_metrics_nonstandard_http_method(self): + httpretty.register_uri( + "NONSTANDARD", self.HTTP_URL, body="", status=405 + ) + + start_time = default_timer() + response = self.pool.request("NONSTANDARD", self.HTTP_URL) + duration_ms = max(round((default_timer() - start_time) * 1000), 0) metrics = self.get_sorted_metrics() @@ -57,27 +235,29 @@ def test_basic_metrics(self): client_response_size, ) = metrics + attrs_old = { + SpanAttributes.HTTP_STATUS_CODE: 405, + SpanAttributes.HTTP_HOST: "mock", + SpanAttributes.NET_PEER_PORT: 80, + SpanAttributes.NET_PEER_NAME: "mock", + SpanAttributes.HTTP_METHOD: "_OTHER", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_SCHEME: "http", + } + self.assertEqual(client_duration.name, "http.client.duration") self.assert_metric_expected( client_duration, [ self.create_histogram_data_point( count=1, - sum_data_point=client_duration_estimated, - max_data_point=client_duration_estimated, - min_data_point=client_duration_estimated, - attributes={ - "http.flavor": "1.1", - "http.host": "mock", - "http.method": "GET", - "http.scheme": "http", - "http.status_code": 200, - "net.peer.name": "mock", - "net.peer.port": 80, - }, + sum_data_point=duration_ms, + max_data_point=duration_ms, + min_data_point=duration_ms, + attributes=attrs_old, ) ], - est_value_delta=200, + est_value_delta=40, ) self.assertEqual(client_request_size.name, "http.client.request.size") @@ -89,15 +269,7 @@ def test_basic_metrics(self): sum_data_point=0, max_data_point=0, min_data_point=0, - attributes={ - "http.flavor": "1.1", - "http.host": "mock", - "http.method": "GET", - "http.scheme": "http", - "http.status_code": 200, - "net.peer.name": "mock", - "net.peer.port": 80, - }, + attributes=attrs_old, ) ], ) @@ -114,15 +286,82 @@ def test_basic_metrics(self): sum_data_point=expected_size, max_data_point=expected_size, min_data_point=expected_size, - attributes={ - "http.flavor": "1.1", - "http.host": "mock", - "http.method": "GET", - "http.scheme": "http", - "http.status_code": 200, - "net.peer.name": "mock", - "net.peer.port": 80, - }, + attributes=attrs_old, + ) + ], + ) + + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) + def test_basic_metrics_nonstandard_http_method_new_semconv(self): + httpretty.register_uri( + "NONSTANDARD", self.HTTP_URL, body="", status=405 + ) + start_time = default_timer() + response = self.pool.request("NONSTANDARD", self.HTTP_URL) + duration_s = max(default_timer() - start_time, 0) + + metrics = self.get_sorted_metrics() + + ( + client_request_size, + client_duration, + client_response_size, + ) = metrics + + attrs_new = { + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_ADDRESS: "mock", + SERVER_PORT: 80, + HTTP_REQUEST_METHOD: "_OTHER", + HTTP_RESPONSE_STATUS_CODE: 405, + "error.type": "405", + # TODO: add URL_SCHEME to tests when supported in the implementation + } + + self.assertEqual(client_duration.name, "http.client.request.duration") + self.assert_metric_expected( + client_duration, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=duration_s, + max_data_point=duration_s, + min_data_point=duration_s, + attributes=attrs_new, + ) + ], + est_value_delta=40 / 1000, + ) + + self.assertEqual( + client_request_size.name, "http.client.request.body.size" + ) + self.assert_metric_expected( + client_request_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=0, + max_data_point=0, + min_data_point=0, + attributes=attrs_new, + ) + ], + ) + + expected_size = len(response.data) + self.assertEqual( + client_response_size.name, "http.client.response.body.size" + ) + self.assert_metric_expected( + client_response_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=expected_size, + max_data_point=expected_size, + min_data_point=expected_size, + attributes=attrs_new, ) ], ) @@ -274,3 +513,5 @@ def test_metric_uninstrument(self): for metric in metrics: for point in list(metric.data.data_points): self.assertEqual(point.count, 1) + # instrument again to avoid warning message on tearDown + URLLib3Instrumentor().instrument() From e799a74bbe62b103bdb5649e4c5849fc977ee35f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 23 Jul 2024 20:09:30 -0300 Subject: [PATCH 113/335] fix schema url in instrumentation tests (#2730) * fix schema url in instrumentation tests * change core repo sha for test * Update CORE_REPO_SHA * Try removing cache * Clear cache here as well --------- Co-authored-by: Diego Hurtado --- .github/workflows/instrumentations_0.yml | 4 ++-- .github/workflows/instrumentations_1.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- .../tests/test_aiohttp_client_integration.py | 4 ++-- .../tests/test_urllib3_integration.py | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index 69c07bfacc..382284d204 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e + CORE_REPO_SHA: main jobs: instrumentations-0: @@ -114,6 +114,6 @@ jobs: path: | .tox ~/.cache/pip - key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} + key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('gen-requirements.txt', 'dev-requirements.txt') }} - name: run tox run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index a658796ef8..f3e63116f8 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e + CORE_REPO_SHA: main jobs: instrumentations-1: @@ -59,6 +59,6 @@ jobs: path: | .tox ~/.cache/pip - key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} + key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('gen-requirements.txt', 'dev-requirements.txt') }} - name: run tox run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 29cd5cac16..b9f7a41c17 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e + CORE_REPO_SHA: main jobs: lint-3_12: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee66efac64..2714942c21 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: 141a6a2e473ef7f0ec4915dfb71e3c0fa595283e + CORE_REPO_SHA: main jobs: misc: diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 3873a6f094..adf54c295b 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -223,7 +223,7 @@ def test_schema_url_new_semconv(self): span = self.memory_exporter.get_finished_spans()[0] self.assertEqual( span.instrumentation_info.schema_url, - "https://opentelemetry.io/schemas/v1.21.0", + "https://opentelemetry.io/schemas/1.21.0", ) self.memory_exporter.clear() @@ -240,7 +240,7 @@ def test_schema_url_both_semconv(self): span = self.memory_exporter.get_finished_spans()[0] self.assertEqual( span.instrumentation_info.schema_url, - "https://opentelemetry.io/schemas/v1.21.0", + "https://opentelemetry.io/schemas/1.21.0", ) self.memory_exporter.clear() diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py index 7dc899691f..5ad4e40ca3 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py @@ -239,7 +239,7 @@ def test_schema_url_new_semconv(self): span = self.assert_span() self.assertEqual( span.instrumentation_scope.schema_url, - "https://opentelemetry.io/schemas/v1.21.0", + "https://opentelemetry.io/schemas/1.21.0", ) def test_schema_url_both_semconv(self): @@ -250,7 +250,7 @@ def test_schema_url_both_semconv(self): span = self.assert_span() self.assertEqual( span.instrumentation_scope.schema_url, - "https://opentelemetry.io/schemas/v1.21.0", + "https://opentelemetry.io/schemas/1.21.0", ) def test_basic_not_found(self): From a47810c2a203f3f6345b18b5f1c47de446bf864e Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 24 Jul 2024 14:55:21 -0600 Subject: [PATCH 114/335] Enable global propagator for AWS instrumentation (#2599) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enable global propagator for AWS instrumentation Fixes #2598 * Add entry point test case * Update instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml Co-authored-by: Riccardo Magliocchetti * Add test for propagator * Fix entry point name * Update instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Try with ubuntu latest * Try with 24.04 * Fix propagator key * Fix lint * Revert ununtuns --------- Co-authored-by: Riccardo Magliocchetti Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- CHANGELOG.md | 2 + .../pyproject.toml | 3 + .../instrumentation/aws_lambda/__init__.py | 55 ++----------------- .../tests/test_aws_lambda_instrumentation.py | 13 ----- .../test_aws_lambda_instrumentation_manual.py | 43 ++++++++++----- .../pyproject.toml | 2 +- .../opentelemetry/propagators/aws/__init__.py | 7 ++- .../propagators/aws/aws_xray_propagator.py | 4 +- .../tests/test_aws_xray_lambda_propagator.py | 23 ++++++-- 9 files changed, 66 insertions(+), 86 deletions(-) delete mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation.py diff --git a/CHANGELOG.md b/CHANGELOG.md index bc400865a2..c759549027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-flask` Add `http.route` and `http.target` to metric attributes ([#2621](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2621)) +- `opentelemetry-instrumentation-aws-lambda` Enable global propagator for AWS instrumentation + ([#2708](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2708)) - `opentelemetry-instrumentation-sklearn` Deprecated the sklearn instrumentation ([#2708](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2708)) - `opentelemetry-instrumentation-pyramid` Record exceptions raised when serving a request diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index cbed1edb9e..c10df60c48 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -33,6 +33,9 @@ dependencies = [ [project.optional-dependencies] instruments = [] +[project.entry-points.opentelemetry_instrumentor] +aws-lambda = "opentelemetry.instrumentation.aws_lambda:AwsLambdaInstrumentor" + [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aws-lambda" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index 4acf4dea90..c320c12bde 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -83,10 +83,6 @@ def custom_event_context_extractor(lambda_event): from opentelemetry.instrumentation.utils import unwrap from opentelemetry.metrics import MeterProvider, get_meter_provider from opentelemetry.propagate import get_global_textmap -from opentelemetry.propagators.aws.aws_xray_propagator import ( - TRACE_HEADER_KEY, - AwsXRayPropagator, -) from opentelemetry.semconv.resource import ResourceAttributes from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import ( @@ -96,7 +92,6 @@ def custom_event_context_extractor(lambda_event): get_tracer, get_tracer_provider, ) -from opentelemetry.trace.propagation import get_current_span from opentelemetry.trace.status import Status, StatusCode logger = logging.getLogger(__name__) @@ -107,9 +102,6 @@ def custom_event_context_extractor(lambda_event): OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT = ( "OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT" ) -OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION = ( - "OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION" -) def _default_event_context_extractor(lambda_event: Any) -> Context: @@ -145,7 +137,6 @@ def _default_event_context_extractor(lambda_event: Any) -> Context: def _determine_parent_context( lambda_event: Any, event_context_extractor: Callable[[Any], Context], - disable_aws_context_propagation: bool = False, ) -> Context: """Determine the parent context for the current Lambda invocation. @@ -159,36 +150,14 @@ def _determine_parent_context( Event as input and extracts an OTel Context from it. By default, the context is extracted from the HTTP headers of an API Gateway request. - disable_aws_context_propagation: By default, this instrumentation - will try to read the context from the `_X_AMZN_TRACE_ID` environment - variable set by Lambda, set this to `True` to disable this behavior. Returns: A Context with configuration found in the carrier. """ - parent_context = None - - if not disable_aws_context_propagation: - xray_env_var = os.environ.get(_X_AMZN_TRACE_ID) - if xray_env_var: - parent_context = AwsXRayPropagator().extract( - {TRACE_HEADER_KEY: xray_env_var} - ) - - if ( - parent_context - and get_current_span(parent_context) - .get_span_context() - .trace_flags.sampled - ): - return parent_context + if event_context_extractor is None: + return _default_event_context_extractor(lambda_event) - if event_context_extractor: - parent_context = event_context_extractor(lambda_event) - else: - parent_context = _default_event_context_extractor(lambda_event) - - return parent_context + return event_context_extractor(lambda_event) def _set_api_gateway_v1_proxy_attributes( @@ -286,14 +255,15 @@ def _instrument( flush_timeout, event_context_extractor: Callable[[Any], Context], tracer_provider: TracerProvider = None, - disable_aws_context_propagation: bool = False, meter_provider: MeterProvider = None, ): + # pylint: disable=too-many-locals # pylint: disable=too-many-statements def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches call_wrapped, instance, args, kwargs ): + orig_handler_name = ".".join( [wrapped_module_name, wrapped_function_name] ) @@ -303,7 +273,6 @@ def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches parent_context = _determine_parent_context( lambda_event, event_context_extractor, - disable_aws_context_propagation, ) try: @@ -451,9 +420,6 @@ def _instrument(self, **kwargs): Event as input and extracts an OTel Context from it. By default, the context is extracted from the HTTP headers of an API Gateway request. - ``disable_aws_context_propagation``: By default, this instrumentation - will try to read the context from the `_X_AMZN_TRACE_ID` environment - variable set by Lambda, set this to `True` to disable this behavior. """ lambda_handler = os.environ.get(ORIG_HANDLER, os.environ.get(_HANDLER)) # pylint: disable=attribute-defined-outside-init @@ -475,16 +441,6 @@ def _instrument(self, **kwargs): flush_timeout_env, ) - disable_aws_context_propagation = kwargs.get( - "disable_aws_context_propagation", False - ) or os.getenv( - OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION, "False" - ).strip().lower() in ( - "true", - "1", - "t", - ) - _instrument( self._wrapped_module_name, self._wrapped_function_name, @@ -493,7 +449,6 @@ def _instrument(self, **kwargs): "event_context_extractor", _default_event_context_extractor ), tracer_provider=kwargs.get("tracer_provider"), - disable_aws_context_propagation=disable_aws_context_propagation, meter_provider=kwargs.get("meter_provider"), ) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation.py deleted file mode 100644 index b0a6f42841..0000000000 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index ecce9ea12c..9f25524e43 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -11,18 +11,19 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + import os from dataclasses import dataclass -from importlib import import_module +from importlib import import_module, reload from typing import Any, Callable, Dict from unittest import mock +from opentelemetry import propagate from opentelemetry.environment_variables import OTEL_PROPAGATORS from opentelemetry.instrumentation.aws_lambda import ( _HANDLER, _X_AMZN_TRACE_ID, OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT, - OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION, AwsLambdaInstrumentor, ) from opentelemetry.propagate import get_global_textmap @@ -37,6 +38,7 @@ from opentelemetry.trace.propagation.tracecontext import ( TraceContextTextMapPropagator, ) +from opentelemetry.util._importlib_metadata import entry_points from .mocks.api_gateway_http_api_event import ( MOCK_LAMBDA_API_GATEWAY_HTTP_API_EVENT, @@ -56,6 +58,7 @@ def __init__(self, aws_request_id, invoked_function_arn): ) MOCK_XRAY_TRACE_ID = 0x5FB7331105E8BB83207FA31D4D9CDB4C + MOCK_XRAY_TRACE_ID_STR = f"{MOCK_XRAY_TRACE_ID:x}" MOCK_XRAY_PARENT_SPAN_ID = 0x3328B8445A6DBAD2 MOCK_XRAY_TRACE_CONTEXT_COMMON = f"Root={TRACE_ID_VERSION}-{MOCK_XRAY_TRACE_ID_STR[:TRACE_ID_FIRST_PART_LENGTH]}-{MOCK_XRAY_TRACE_ID_STR[TRACE_ID_FIRST_PART_LENGTH:]};Parent={MOCK_XRAY_PARENT_SPAN_ID:x}" @@ -81,6 +84,7 @@ def mock_execute_lambda(event=None): """Mocks the AWS Lambda execution. NOTE: We don't use `moto`'s `mock_lambda` because we are not instrumenting + calls to AWS Lambda using the AWS SDK. Instead, we are instrumenting AWS Lambda itself. @@ -122,10 +126,13 @@ def test_active_tracing(self): { **os.environ, # Using Active tracing + OTEL_PROPAGATORS: "xray-lambda", _X_AMZN_TRACE_ID: MOCK_XRAY_TRACE_CONTEXT_SAMPLED, }, ) + test_env_patch.start() + reload(propagate) AwsLambdaInstrumentor().instrument() @@ -173,8 +180,7 @@ class TestCase: xray_traceid: str expected_state_value: str = None expected_trace_state_len: int = 0 - disable_aws_context_propagation: bool = False - disable_aws_context_propagation_envvar: str = "" + propagators: str = "tracecontext" def custom_event_context_extractor(lambda_event): return get_global_textmap().extract(lambda_event["foo"]["headers"]) @@ -226,9 +232,10 @@ def custom_event_context_extractor(lambda_event): expected_traceid=MOCK_XRAY_TRACE_ID, expected_parentid=MOCK_XRAY_PARENT_SPAN_ID, xray_traceid=MOCK_XRAY_TRACE_CONTEXT_SAMPLED, + propagators="xray-lambda", ), TestCase( - name="custom_extractor_sampled_xray_disable_aws_propagation", + name="custom_extractor_sampled_xray", custom_extractor=custom_event_context_extractor, context={ "foo": { @@ -238,7 +245,6 @@ def custom_event_context_extractor(lambda_event): } } }, - disable_aws_context_propagation=True, expected_traceid=MOCK_W3C_TRACE_ID, expected_parentid=MOCK_W3C_PARENT_SPAN_ID, expected_trace_state_len=3, @@ -246,7 +252,7 @@ def custom_event_context_extractor(lambda_event): xray_traceid=MOCK_XRAY_TRACE_CONTEXT_SAMPLED, ), TestCase( - name="no_custom_extractor_xray_disable_aws_propagation_via_env_var", + name="no_custom_extractor_xray", custom_extractor=None, context={ "headers": { @@ -254,8 +260,6 @@ def custom_event_context_extractor(lambda_event): TraceContextTextMapPropagator._TRACESTATE_HEADER_NAME: f"{MOCK_W3C_TRACE_STATE_KEY}={MOCK_W3C_TRACE_STATE_VALUE},foo=1,bar=2", } }, - disable_aws_context_propagation=False, - disable_aws_context_propagation_envvar="true", expected_traceid=MOCK_W3C_TRACE_ID, expected_parentid=MOCK_W3C_PARENT_SPAN_ID, expected_trace_state_len=3, @@ -264,21 +268,21 @@ def custom_event_context_extractor(lambda_event): ), ] for test in tests: + test_env_patch = mock.patch.dict( "os.environ", { **os.environ, # NOT Active Tracing _X_AMZN_TRACE_ID: test.xray_traceid, - OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION: test.disable_aws_context_propagation_envvar, - # NOT using the X-Ray Propagator - OTEL_PROPAGATORS: "tracecontext", + OTEL_PROPAGATORS: test.propagators, }, ) test_env_patch.start() + reload(propagate) + AwsLambdaInstrumentor().instrument( event_context_extractor=test.custom_extractor, - disable_aws_context_propagation=test.disable_aws_context_propagation, ) mock_execute_lambda(test.context) spans = self.memory_exporter.get_finished_spans() @@ -374,6 +378,7 @@ def test_lambda_handles_invalid_event_source(self): }, ) test_env_patch.start() + reload(propagate) AwsLambdaInstrumentor().instrument() @@ -513,3 +518,15 @@ def test_no_op_tracer_provider(self): spans = self.memory_exporter.get_finished_spans() assert spans is not None self.assertEqual(len(spans), 0) + + def test_load_entry_point(self): + self.assertIs( + next( + iter( + entry_points( + group="opentelemetry_instrumentor", name="aws-lambda" + ) + ) + ).load(), + AwsLambdaInstrumentor, + ) diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 4a3e22269a..546c0790a2 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ [project.entry-points.opentelemetry_propagator] xray = "opentelemetry.propagators.aws:AwsXRayPropagator" -xray_lambda = "opentelemetry.propagators.aws:AwsXRayLambdaPropagator" +xray-lambda = "opentelemetry.propagators.aws:AwsXRayLambdaPropagator" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/propagator/opentelemetry-propagator-aws-xray" diff --git a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/__init__.py b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/__init__.py index f28f1c8b15..5520086559 100644 --- a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/__init__.py +++ b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/__init__.py @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from opentelemetry.propagators.aws.aws_xray_propagator import AwsXRayPropagator +from opentelemetry.propagators.aws.aws_xray_propagator import ( + AwsXRayLambdaPropagator, + AwsXRayPropagator, +) -__all__ = ["AwsXRayPropagator"] +__all__ = ["AwsXRayPropagator", "AwsXRayLambdaPropagator"] diff --git a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py index 4966218211..295a5def9b 100644 --- a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py +++ b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py @@ -328,9 +328,9 @@ def fields(self): return {TRACE_HEADER_KEY} -class AwsXrayLambdaPropagator(AwsXRayPropagator): +class AwsXRayLambdaPropagator(AwsXRayPropagator): """Implementation of the AWS X-Ray Trace Header propagation protocol but - with special handling for Lambda's ``_X_AMZN_TRACE_ID` environment + with special handling for Lambda's ``_X_AMZN_TRACE_ID`` environment variable. """ diff --git a/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py b/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py index a0432d1457..2d8937e1b3 100644 --- a/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py +++ b/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py @@ -21,7 +21,7 @@ from opentelemetry.context import get_current from opentelemetry.propagators.aws.aws_xray_propagator import ( TRACE_HEADER_KEY, - AwsXrayLambdaPropagator, + AwsXRayLambdaPropagator, ) from opentelemetry.propagators.textmap import DefaultGetter from opentelemetry.sdk.trace import ReadableSpan @@ -33,6 +33,7 @@ get_current_span, use_span, ) +from opentelemetry.util._importlib_metadata import entry_points class AwsXRayLambdaPropagatorTest(TestCase): @@ -40,7 +41,7 @@ class AwsXRayLambdaPropagatorTest(TestCase): def test_extract_no_environment_variable(self): actual_context = get_current_span( - AwsXrayLambdaPropagator().extract( + AwsXRayLambdaPropagator().extract( {}, context=get_current(), getter=DefaultGetter() ) ).get_span_context() @@ -57,7 +58,7 @@ def test_extract_no_environment_variable_valid_context(self): with use_span(NonRecordingSpan(SpanContext(1, 2, False))): actual_context = get_current_span( - AwsXrayLambdaPropagator().extract( + AwsXRayLambdaPropagator().extract( {}, context=get_current(), getter=DefaultGetter() ) ).get_span_context() @@ -83,7 +84,7 @@ def test_extract_no_environment_variable_valid_context(self): def test_extract_from_environment_variable(self): actual_context = get_current_span( - AwsXrayLambdaPropagator().extract( + AwsXRayLambdaPropagator().extract( {}, context=get_current(), getter=DefaultGetter() ) ).get_span_context() @@ -108,7 +109,7 @@ def test_extract_from_environment_variable(self): ) def test_add_link_from_environment_variable(self): - propagator = AwsXrayLambdaPropagator() + propagator = AwsXRayLambdaPropagator() default_getter = DefaultGetter() @@ -162,3 +163,15 @@ def test_add_link_from_environment_variable(self): self.assertEqual( span_link_context.trace_state, TraceState.get_default() ) + + def test_load_entry_point(self): + self.assertIs( + next( + iter( + entry_points( + group="opentelemetry_propagator", name="xray-lambda" + ) + ) + ).load(), + AwsXRayLambdaPropagator, + ) From 68b20f96c5c1500bec5196a2418d0e8542b15450 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 25 Jul 2024 05:18:49 +0200 Subject: [PATCH 115/335] Update version to 1.27.0.dev/0.48b0.dev (#2728) * Update version to 1.27.0.dev/0.48b0.dev * Update SHA and fix test cases * Update SHA --------- Co-authored-by: Diego Hurtado --- .github/workflows/instrumentations_0.yml | 2 +- .github/workflows/instrumentations_1.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- CHANGELOG.md | 2 + _template/version.py | 2 +- eachdist.ini | 4 +- .../prometheus_remote_write/version.py | 2 +- .../pyproject.toml | 2 +- .../exporter/richconsole/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/aio_pika/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_client/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_server/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiopg/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asgi/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asyncio/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncpg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aws_lambda/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto3sqs/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/botocore/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/cassandra/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/celery/version.py | 2 +- .../pyproject.toml | 2 +- .../confluent_kafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/dbapi/version.py | 2 +- .../pyproject.toml | 10 +- .../instrumentation/django/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/elasticsearch/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/falcon/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/fastapi/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/flask/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/grpc/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/httpx/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/jinja2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/kafka/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/logging/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysqlclient/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymemcache/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymongo/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymysql/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/pyramid/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/redis/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/remoulade/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/requests/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlalchemy/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlite3/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/starlette/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/system_metrics/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/threading/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/tornado/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/tortoiseorm/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib3/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/wsgi/version.py | 2 +- .../pyproject.toml | 94 ++++++++-------- .../contrib-instrumentations/version.py | 2 +- opentelemetry-distro/pyproject.toml | 4 +- .../src/opentelemetry/distro/version.py | 2 +- .../instrumentation/bootstrap_gen.py | 100 +++++++++--------- .../opentelemetry/instrumentation/version.py | 2 +- .../processor/baggage/version.py | 2 +- .../propagators/ot_trace/version.py | 2 +- .../resource/detector/container/version.py | 2 +- .../src/opentelemetry/util/http/version.py | 2 +- 114 files changed, 275 insertions(+), 273 deletions(-) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index 382284d204..972a33532c 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 jobs: instrumentations-0: diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index f3e63116f8..1698a49be8 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 jobs: instrumentations-1: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b9f7a41c17..0e2dc7110d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 jobs: lint-3_12: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2714942c21..d749788204 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 jobs: misc: diff --git a/CHANGELOG.md b/CHANGELOG.md index c759549027..b339f8a21e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 1.26.0/0.47b0 (2024-07-23) + ### Added - `opentelemetry-instrumentation-flask` Add `http.route` and `http.target` to metric attributes diff --git a/_template/version.py b/_template/version.py index b6955b0eca..4d21fcb843 100644 --- a/_template/version.py +++ b/_template/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/eachdist.ini b/eachdist.ini index b698eaf299..2bcbde9c7c 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -16,7 +16,7 @@ sortfirst= ext/* [stable] -version=1.26.0.dev +version=1.27.0.dev packages= opentelemetry-sdk @@ -34,7 +34,7 @@ packages= opentelemetry-api [prerelease] -version=0.47b0.dev +version=0.48b0.dev packages= all diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py index b6955b0eca..4d21fcb843 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 745a3bc25d..6d38226160 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-sdk ~= 1.12", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "rich>=10.0.0", ] diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py index b6955b0eca..4d21fcb843 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 3907320999..c8be384fe6 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index f8b4750872..cfc53f723a 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py index deef26c62f..aa0c1a911f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index cd5516c8f6..6d62bd7956 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index e9e7f7f613..404bc9c445 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index d733700a15..480ca75df7 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ dependencies = [ "asgiref ~= 3.0", "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index 2a53899ecd..bac1400a38 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.14", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-test-utils == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-test-utils == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index f5d4ffd1f6..820c86070d 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index c10df60c48..4d6b431d91 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-propagator-aws-xray == 1.0.1", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index 8ddd1f3884..3abda7b175 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index e8a2196483..cbbf9cd679 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 6c92273301..4714a7261f 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "opentelemetry-propagator-aws-xray == 1.0.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 17596cee98..b2ee19bdd2 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 72808bbda7..0d302a4206 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 94a2497b36..13433ba9e2 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-api ~= 1.12", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index 6a81203f01..991c7bb8af 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py index db4e3a0022..e0bef4b1e3 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index e1f67c283d..a8b53820bc 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -26,15 +26,15 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-wsgi == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-wsgi == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] asgi = [ - "opentelemetry-instrumentation-asgi == 0.47b0.dev", + "opentelemetry-instrumentation-asgi == 0.48b0.dev", ] instruments = [ "django >= 1.10", diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index d6e8408738..29d7bec6cc 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 5e0bcdad19..6f505f60ae 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-wsgi == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-wsgi == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", "packaging >= 20.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 1ef5507504..4236fde227 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-asgi == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-asgi == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 1b769d2957..ffafdbacc6 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-wsgi == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-wsgi == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", "packaging >= 21.0", "importlib-metadata >= 4.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index d43c5ed173..d0a7d54298 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index de890755dc..5e4629e281 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index 78417289df..f74b8ca488 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index bd06b90f06..f9c0cf8332 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 658d4eac3c..2c1b2ad897 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py index db4e3a0022..e0bef4b1e3 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 58982a6781..cb1c51b082 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index c36f0e1c55..0ede691e36 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 8cff4d3d24..145439b242 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", "wrapt >= 1.0.0, < 2.0.0", diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 81baee5267..717257821d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 581ff20229..7db83dcc5c 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index eab52fa474..47df236c42 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index d77e95b90e..ccd75ffeaa 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index bc06e31b86..08ee94fd9e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 96edbff3b2..9da43f444c 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-wsgi == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-wsgi == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index af342aa076..d39bda20a5 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "wrapt >= 1.12.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index d3c1bd345d..8b2b3679a9 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index 504634007c..88996d2540 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index c9a54920a2..21021fb590 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", "packaging >= 21.0", "wrapt >= 1.11.2", ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index 09f302e64e..e86fb99235 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-dbapi == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-dbapi == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py index db4e3a0022..e0bef4b1e3 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 9103dd6f2a..6e6d370b53 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-instrumentation-asgi == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation-asgi == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 8518ddc8db..6a1e83912f 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-api ~= 1.11", "psutil >= 5.9.0, < 7", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index d496b99f7a..16088e7de3 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index ab5d522aa2..0096deb8fd 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index dc0293d3d5..04d81e1894 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 90799c4492..4f0d2681f9 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index db4e3a0022..e0bef4b1e3 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index b9dd6d528f..03c9f26fbc 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index e56e4e9eb9..b38f1829aa 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", - "opentelemetry-semantic-conventions == 0.47b0.dev", - "opentelemetry-util-http == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-util-http == 0.48b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py index b6955b0eca..4d21fcb843 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index f83b9d5ee5..6c7716bad2 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -29,53 +29,53 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation-aio-pika==0.47b0.dev", - "opentelemetry-instrumentation-aiohttp-client==0.47b0.dev", - "opentelemetry-instrumentation-aiohttp-server==0.47b0.dev", - "opentelemetry-instrumentation-aiopg==0.47b0.dev", - "opentelemetry-instrumentation-asgi==0.47b0.dev", - "opentelemetry-instrumentation-asyncio==0.47b0.dev", - "opentelemetry-instrumentation-asyncpg==0.47b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.47b0.dev", - "opentelemetry-instrumentation-boto==0.47b0.dev", - "opentelemetry-instrumentation-boto3sqs==0.47b0.dev", - "opentelemetry-instrumentation-botocore==0.47b0.dev", - "opentelemetry-instrumentation-cassandra==0.47b0.dev", - "opentelemetry-instrumentation-celery==0.47b0.dev", - "opentelemetry-instrumentation-confluent-kafka==0.47b0.dev", - "opentelemetry-instrumentation-dbapi==0.47b0.dev", - "opentelemetry-instrumentation-django==0.47b0.dev", - "opentelemetry-instrumentation-elasticsearch==0.47b0.dev", - "opentelemetry-instrumentation-falcon==0.47b0.dev", - "opentelemetry-instrumentation-fastapi==0.47b0.dev", - "opentelemetry-instrumentation-flask==0.47b0.dev", - "opentelemetry-instrumentation-grpc==0.47b0.dev", - "opentelemetry-instrumentation-httpx==0.47b0.dev", - "opentelemetry-instrumentation-jinja2==0.47b0.dev", - "opentelemetry-instrumentation-kafka-python==0.47b0.dev", - "opentelemetry-instrumentation-logging==0.47b0.dev", - "opentelemetry-instrumentation-mysql==0.47b0.dev", - "opentelemetry-instrumentation-mysqlclient==0.47b0.dev", - "opentelemetry-instrumentation-pika==0.47b0.dev", - "opentelemetry-instrumentation-psycopg==0.47b0.dev", - "opentelemetry-instrumentation-psycopg2==0.47b0.dev", - "opentelemetry-instrumentation-pymemcache==0.47b0.dev", - "opentelemetry-instrumentation-pymongo==0.47b0.dev", - "opentelemetry-instrumentation-pymysql==0.47b0.dev", - "opentelemetry-instrumentation-pyramid==0.47b0.dev", - "opentelemetry-instrumentation-redis==0.47b0.dev", - "opentelemetry-instrumentation-remoulade==0.47b0.dev", - "opentelemetry-instrumentation-requests==0.47b0.dev", - "opentelemetry-instrumentation-sqlalchemy==0.47b0.dev", - "opentelemetry-instrumentation-sqlite3==0.47b0.dev", - "opentelemetry-instrumentation-starlette==0.47b0.dev", - "opentelemetry-instrumentation-system-metrics==0.47b0.dev", - "opentelemetry-instrumentation-threading==0.47b0.dev", - "opentelemetry-instrumentation-tornado==0.47b0.dev", - "opentelemetry-instrumentation-tortoiseorm==0.47b0.dev", - "opentelemetry-instrumentation-urllib==0.47b0.dev", - "opentelemetry-instrumentation-urllib3==0.47b0.dev", - "opentelemetry-instrumentation-wsgi==0.47b0.dev", + "opentelemetry-instrumentation-aio-pika==0.48b0.dev", + "opentelemetry-instrumentation-aiohttp-client==0.48b0.dev", + "opentelemetry-instrumentation-aiohttp-server==0.48b0.dev", + "opentelemetry-instrumentation-aiopg==0.48b0.dev", + "opentelemetry-instrumentation-asgi==0.48b0.dev", + "opentelemetry-instrumentation-asyncio==0.48b0.dev", + "opentelemetry-instrumentation-asyncpg==0.48b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.48b0.dev", + "opentelemetry-instrumentation-boto==0.48b0.dev", + "opentelemetry-instrumentation-boto3sqs==0.48b0.dev", + "opentelemetry-instrumentation-botocore==0.48b0.dev", + "opentelemetry-instrumentation-cassandra==0.48b0.dev", + "opentelemetry-instrumentation-celery==0.48b0.dev", + "opentelemetry-instrumentation-confluent-kafka==0.48b0.dev", + "opentelemetry-instrumentation-dbapi==0.48b0.dev", + "opentelemetry-instrumentation-django==0.48b0.dev", + "opentelemetry-instrumentation-elasticsearch==0.48b0.dev", + "opentelemetry-instrumentation-falcon==0.48b0.dev", + "opentelemetry-instrumentation-fastapi==0.48b0.dev", + "opentelemetry-instrumentation-flask==0.48b0.dev", + "opentelemetry-instrumentation-grpc==0.48b0.dev", + "opentelemetry-instrumentation-httpx==0.48b0.dev", + "opentelemetry-instrumentation-jinja2==0.48b0.dev", + "opentelemetry-instrumentation-kafka-python==0.48b0.dev", + "opentelemetry-instrumentation-logging==0.48b0.dev", + "opentelemetry-instrumentation-mysql==0.48b0.dev", + "opentelemetry-instrumentation-mysqlclient==0.48b0.dev", + "opentelemetry-instrumentation-pika==0.48b0.dev", + "opentelemetry-instrumentation-psycopg==0.48b0.dev", + "opentelemetry-instrumentation-psycopg2==0.48b0.dev", + "opentelemetry-instrumentation-pymemcache==0.48b0.dev", + "opentelemetry-instrumentation-pymongo==0.48b0.dev", + "opentelemetry-instrumentation-pymysql==0.48b0.dev", + "opentelemetry-instrumentation-pyramid==0.48b0.dev", + "opentelemetry-instrumentation-redis==0.48b0.dev", + "opentelemetry-instrumentation-remoulade==0.48b0.dev", + "opentelemetry-instrumentation-requests==0.48b0.dev", + "opentelemetry-instrumentation-sqlalchemy==0.48b0.dev", + "opentelemetry-instrumentation-sqlite3==0.48b0.dev", + "opentelemetry-instrumentation-starlette==0.48b0.dev", + "opentelemetry-instrumentation-system-metrics==0.48b0.dev", + "opentelemetry-instrumentation-threading==0.48b0.dev", + "opentelemetry-instrumentation-tornado==0.48b0.dev", + "opentelemetry-instrumentation-tortoiseorm==0.48b0.dev", + "opentelemetry-instrumentation-urllib==0.48b0.dev", + "opentelemetry-instrumentation-urllib3==0.48b0.dev", + "opentelemetry-instrumentation-wsgi==0.48b0.dev", ] [project.urls] diff --git a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py index b6955b0eca..4d21fcb843 100644 --- a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py +++ b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 17f8e5de43..2397e9182a 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -27,13 +27,13 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.47b0.dev", + "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-sdk ~= 1.13", ] [project.optional-dependencies] otlp = [ - "opentelemetry-exporter-otlp == 1.26.0.dev", + "opentelemetry-exporter-otlp == 1.27.0.dev", ] [project.entry-points.opentelemetry_configurator] diff --git a/opentelemetry-distro/src/opentelemetry/distro/version.py b/opentelemetry-distro/src/opentelemetry/distro/version.py index b6955b0eca..4d21fcb843 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/version.py +++ b/opentelemetry-distro/src/opentelemetry/distro/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 9b71a8bdff..4ad6824281 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -18,180 +18,180 @@ libraries = [ { "library": "aio_pika >= 7.2.0, < 10.0.0", - "instrumentation": "opentelemetry-instrumentation-aio-pika==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-aio-pika==0.48b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.48b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.48b0.dev", }, { "library": "aiopg >= 0.13.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiopg==0.48b0.dev", }, { "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-asgi==0.48b0.dev", }, { "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncpg==0.48b0.dev", }, { "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto==0.48b0.dev", }, { "library": "boto3 ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.48b0.dev", }, { "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.48b0.dev", }, { "library": "cassandra-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.48b0.dev", }, { "library": "scylla-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.48b0.dev", }, { "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-celery==0.48b0.dev", }, { "library": "confluent-kafka >= 1.8.2, <= 2.4.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.48b0.dev", }, { "library": "django >= 1.10", - "instrumentation": "opentelemetry-instrumentation-django==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-django==0.48b0.dev", }, { "library": "elasticsearch >= 6.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.48b0.dev", }, { "library": "falcon >= 1.4.1, < 3.1.2", - "instrumentation": "opentelemetry-instrumentation-falcon==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-falcon==0.48b0.dev", }, { "library": "fastapi ~= 0.58", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", }, { "library": "fastapi-slim ~= 0.111.0", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", }, { "library": "flask >= 1.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-flask==0.48b0.dev", }, { "library": "grpcio ~= 1.27", - "instrumentation": "opentelemetry-instrumentation-grpc==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-grpc==0.48b0.dev", }, { "library": "httpx >= 0.18.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-httpx==0.48b0.dev", }, { "library": "jinja2 >= 2.7, < 4.0", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-jinja2==0.48b0.dev", }, { "library": "kafka-python >= 2.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.48b0.dev", }, { "library": "mysql-connector-python ~= 8.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysql==0.48b0.dev", }, { "library": "mysqlclient < 3", - "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.48b0.dev", }, { "library": "pika >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-pika==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-pika==0.48b0.dev", }, { "library": "psycopg >= 3.1.0", - "instrumentation": "opentelemetry-instrumentation-psycopg==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg==0.48b0.dev", }, { "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.48b0.dev", }, { "library": "pymemcache >= 1.3.5, < 5", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymemcache==0.48b0.dev", }, { "library": "pymongo >= 3.1, < 5.0", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymongo==0.48b0.dev", }, { "library": "PyMySQL < 2", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymysql==0.48b0.dev", }, { "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-pyramid==0.48b0.dev", }, { "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-redis==0.48b0.dev", }, { "library": "remoulade >= 0.50", - "instrumentation": "opentelemetry-instrumentation-remoulade==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-remoulade==0.48b0.dev", }, { "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-requests==0.48b0.dev", }, { "library": "sqlalchemy", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.48b0.dev", }, { "library": "starlette ~= 0.13.0", - "instrumentation": "opentelemetry-instrumentation-starlette==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-starlette==0.48b0.dev", }, { "library": "psutil >= 5", - "instrumentation": "opentelemetry-instrumentation-system-metrics==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-system-metrics==0.48b0.dev", }, { "library": "tornado >= 5.1.1", - "instrumentation": "opentelemetry-instrumentation-tornado==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-tornado==0.48b0.dev", }, { "library": "tortoise-orm >= 0.17.0", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.48b0.dev", }, { "library": "pydantic >= 1.10.2", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.48b0.dev", }, { "library": "urllib3 >= 1.0.0, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.47b0.dev", + "instrumentation": "opentelemetry-instrumentation-urllib3==0.48b0.dev", }, ] default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.47b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.47b0.dev", - "opentelemetry-instrumentation-dbapi==0.47b0.dev", - "opentelemetry-instrumentation-logging==0.47b0.dev", - "opentelemetry-instrumentation-sqlite3==0.47b0.dev", - "opentelemetry-instrumentation-threading==0.47b0.dev", - "opentelemetry-instrumentation-urllib==0.47b0.dev", - "opentelemetry-instrumentation-wsgi==0.47b0.dev", + "opentelemetry-instrumentation-asyncio==0.48b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.48b0.dev", + "opentelemetry-instrumentation-dbapi==0.48b0.dev", + "opentelemetry-instrumentation-logging==0.48b0.dev", + "opentelemetry-instrumentation-sqlite3==0.48b0.dev", + "opentelemetry-instrumentation-threading==0.48b0.dev", + "opentelemetry-instrumentation-urllib==0.48b0.dev", + "opentelemetry-instrumentation-wsgi==0.48b0.dev", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index b6955b0eca..4d21fcb843 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py index b6955b0eca..4d21fcb843 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py index b6955b0eca..4d21fcb843 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py index b6955b0eca..4d21fcb843 100644 --- a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py +++ b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py index b6955b0eca..4d21fcb843 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.47b0.dev" +__version__ = "0.48b0.dev" From 6690ecc441de092dfb3fb109174aaae7fb15ae34 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 25 Jul 2024 11:39:17 -0700 Subject: [PATCH 116/335] add srprash as component owner of aws extension (#2741) --- .github/component_owners.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index efd15a6775..b092d5d2c3 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -35,6 +35,7 @@ components: sdk-extension/opentelemetry-sdk-extension-aws: - NathanielRN - Kausik-A + - srprash instrumentation/opentelemetry-instrumentation-tortoiseorm: - tonybaloney From 4f985196c6f89d5d246af9679084dd5bd73b9f9f Mon Sep 17 00:00:00 2001 From: Pavel Perestoronin Date: Fri, 26 Jul 2024 00:08:26 +0200 Subject: [PATCH 117/335] feat(urllib3)!: refactor request hook parameters (#2711) --- CHANGELOG.md | 1 + .../instrumentation/urllib3/__init__.py | 52 +++++++++++++++---- .../tests/test_urllib3_integration.py | 34 +++++++++--- 3 files changed, 68 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b339f8a21e..7924d9211e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2726](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2726)) - `opentelemetry-instrumentation-fastapi` Add dependency support for fastapi-slim ([#2702](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2702)) +- `opentelemetry-instrumentation-urllib3` improve request_hook, replacing `headers` and `body` parameters with a single `request_info: RequestInfo` parameter that now contains the `method` and `url` ([#2711](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2711)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index a05084725d..4bcd0816fd 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -47,14 +47,19 @@ def strip_query_params(url: str) -> str: .. code:: python - # `request` is an instance of urllib3.connectionpool.HTTPConnectionPool - def request_hook(span, request): - pass - - # `request` is an instance of urllib3.connectionpool.HTTPConnectionPool - # `response` is an instance of urllib3.response.HTTPResponse - def response_hook(span, request, response): - pass + def request_hook( + span: Span, + pool: urllib3.connectionpool.HTTPConnectionPool, + request_info: RequestInfo, + ) -> Any: + ... + + def response_hook( + span: Span, + pool: urllib3.connectionpool.HTTPConnectionPool, + response: urllib3.response.HTTPResponse, + ) -> Any: + ... URLLib3Instrumentor().instrument( request_hook=request_hook, response_hook=response_hook @@ -81,6 +86,7 @@ def response_hook(span, request, response): import collections.abc import io import typing +from dataclasses import dataclass from timeit import default_timer from typing import Collection @@ -135,14 +141,29 @@ def response_hook(span, request, response): _excluded_urls_from_env = get_excluded_urls("URLLIB3") + +@dataclass +class RequestInfo: + """Arguments that were passed to the ``urlopen()`` call.""" + + __slots__ = ("method", "url", "headers", "body") + + # The type annotations here come from ``HTTPConnectionPool.urlopen()``. + method: str + url: str + headers: typing.Optional[typing.Mapping[str, str]] + body: typing.Union[ + bytes, typing.IO[typing.Any], typing.Iterable[bytes], str, None + ] + + _UrlFilterT = typing.Optional[typing.Callable[[str], str]] _RequestHookT = typing.Optional[ typing.Callable[ [ Span, urllib3.connectionpool.HTTPConnectionPool, - typing.Dict, - typing.Optional[str], + RequestInfo, ], None, ] @@ -317,7 +338,16 @@ def instrumented_urlopen(wrapped, instance, args, kwargs): span_name, kind=SpanKind.CLIENT, attributes=span_attributes ) as span, set_ip_on_next_http_connection(span): if callable(request_hook): - request_hook(span, instance, headers, body) + request_hook( + span, + instance, + RequestInfo( + method=method, + url=url, + headers=headers, + body=body, + ), + ) inject(headers) # TODO: add error handling to also set exception `error.type` in new semconv with suppress_http_instrumentation(): diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py index 5ad4e40ca3..0e6037ed11 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py @@ -27,7 +27,10 @@ _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, ) -from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor +from opentelemetry.instrumentation.urllib3 import ( + RequestInfo, + URLLib3Instrumentor, +) from opentelemetry.instrumentation.utils import ( suppress_http_instrumentation, suppress_instrumentation, @@ -42,6 +45,7 @@ from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase +from opentelemetry.trace import Span from opentelemetry.util.http import get_excluded_urls # pylint: disable=too-many-public-methods @@ -521,10 +525,10 @@ def test_credential_removal(self): self.assert_success_span(response, self.HTTP_URL) def test_hooks(self): - def request_hook(span, request, body, headers): + def request_hook(span, pool, request_info): span.update_name("name set from hook") - def response_hook(span, request, response): + def response_hook(span, pool, response): span.set_attribute("response_hook_attr", "value") URLLib3Instrumentor().uninstrument() @@ -541,11 +545,17 @@ def response_hook(span, request, response): self.assertEqual(span.attributes["response_hook_attr"], "value") def test_request_hook_params(self): - def request_hook(span, request, headers, body): + def request_hook( + span: Span, + _pool: urllib3.connectionpool.ConnectionPool, + request_info: RequestInfo, + ) -> None: + span.set_attribute("request_hook_method", request_info.method) + span.set_attribute("request_hook_url", request_info.url) span.set_attribute( - "request_hook_headers", json.dumps(dict(headers)) + "request_hook_headers", json.dumps(dict(request_info.headers)) ) - span.set_attribute("request_hook_body", body) + span.set_attribute("request_hook_body", request_info.body) URLLib3Instrumentor().uninstrument() URLLib3Instrumentor().instrument( @@ -564,6 +574,10 @@ def request_hook(span, request, headers, body): span = self.assert_span() + self.assertEqual(span.attributes["request_hook_method"], "POST") + self.assertEqual( + span.attributes["request_hook_url"], "http://mock/status/200" + ) self.assertIn("request_hook_headers", span.attributes) self.assertEqual( span.attributes["request_hook_headers"], json.dumps(headers) @@ -572,8 +586,12 @@ def request_hook(span, request, headers, body): self.assertEqual(span.attributes["request_hook_body"], body) def test_request_positional_body(self): - def request_hook(span, request, headers, body): - span.set_attribute("request_hook_body", body) + def request_hook( + span: Span, + _pool: urllib3.connectionpool.ConnectionPool, + request_info: RequestInfo, + ) -> None: + span.set_attribute("request_hook_body", request_info.body) URLLib3Instrumentor().uninstrument() URLLib3Instrumentor().instrument( From 26ab80925fb32aea274db9c88b5826197a6b1265 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Fri, 26 Jul 2024 08:04:09 -0700 Subject: [PATCH 118/335] Remove extra duration check in fastapi test (#2743) --- .../tests/test_fastapi_instrumentation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 69c5d312e5..d233331283 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -768,7 +768,6 @@ def test_basic_metric_nonstandard_http_method_success_both_semconv(self): for point in list(metric.data.data_points): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) - self.assertAlmostEqual(duration, point.sum, delta=40) if metric.name == "http.server.request.duration": self.assertAlmostEqual(duration_s, point.sum, places=1) self.assertDictEqual( From 5a48824f4f6c09c1583fafc44ba9cdf1e4293569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:13:17 -0300 Subject: [PATCH 119/335] Update pyproject.toml (#2740) --- .../opentelemetry-instrumentation-asyncio/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index bac1400a38..cda5403ef5 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -28,7 +28,6 @@ dependencies = [ "opentelemetry-api ~= 1.14", "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-test-utils == 0.48b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] From c45a6201e234f73322fcbcb858e906a55d349796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:51:12 -0300 Subject: [PATCH 120/335] remove unecessary packages for sqlalchemy tests (#2742) --- .../test-requirements-0.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index af0e495a39..407222e8f6 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -1,15 +1,12 @@ asgiref==3.7.2 cffi==1.15.1 Deprecated==1.2.14 -greenlet==0.4.13 -hpy==0.0.4.dev179+g9b5d200 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -readline==6.2.4.1 SQLAlchemy==1.1.18 tomli==2.0.1 typing_extensions==4.10.0 From 33ad0dc01212067c7dc597ecb0aa779aa5e2f3a7 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 29 Jul 2024 11:57:36 -0700 Subject: [PATCH 121/335] =?UTF-8?q?Include=20dummy=20version=20upload=20as?= =?UTF-8?q?=20part=20of=20contributing=20process=20to=20mitig=E2=80=A6=20(?= =?UTF-8?q?#2747)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 3 ++- RELEASING.md | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ab75ce1c6..302e2e7481 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -250,7 +250,8 @@ The continuous integration overrides that environment variable with as per the c Below is a checklist of things to be mindful of when implementing a new instrumentation or working on a specific instrumentation. It is one of our goals as a community to keep the implementation specific details of instrumentations as similar across the board as possible for ease of testing and feature parity. It is also good to abstract as much common functionality as possible. - Follow semantic conventions - - The instrumentation should follow the semantic conventions defined [here](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/semantic-conventions.md) + - The instrumentation should follow the semantic conventions defined [here](https://github.com/open-telemetry/semantic-conventions/tree/main/docs) +- Contains a name that is not already claimed in [Pypi](https://pypi.org/). Contact a maintainer, bring the issue up in the weekly Python SIG or create a ticket in Pypi if a desired name has already been taken. - Extends from [BaseInstrumentor](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/2518a4ac07cb62ad6587dd8f6cbb5f8663a7e179/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py#L35) - Supports auto-instrumentation - Add an entry point (ex. ) diff --git a/RELEASING.md b/RELEASING.md index 256674d1b8..5a359159fb 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -90,6 +90,10 @@ . If the build has not run automatically, it can be manually trigger via the readthedocs interface. +## Releasing dev version of new packages to claim namespace + +When a contribution introduces a new package, in order to mitigate name-squatting incidents, release the current development version of the new package under the `opentelemetry` user to simply claim the namespace. This should be done shortly after the PR that introduced this package has been merged into `main`. + ## Troubleshooting ### Publish failed From dbfa6818bf856b148824c2ac07b73023a5c1dfaf Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 29 Jul 2024 16:37:44 -0600 Subject: [PATCH 122/335] Add missing requirements and test processor baggage in CI (#2717) * Add missing requirements and test processor baggage in CI Fixes #2716 * Add SDK dependency --- .github/workflows/instrumentations_1.yml | 1 + processor/opentelemetry-processor-baggage/pyproject.toml | 1 + .../test-requirements.txt | 9 +++++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 1698a49be8..48d0839f81 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -39,6 +39,7 @@ jobs: - "resource-detector-container" - "util-http" - "fastapi-slim" + - "processor-baggage" os: [ubuntu-20.04] exclude: - python-version: pypy3 diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 3fa80e1517..29fc2e8681 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", + "opentelemetry-sdk ~= 1.5", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/processor/opentelemetry-processor-baggage/test-requirements.txt b/processor/opentelemetry-processor-baggage/test-requirements.txt index fa7ad3d793..7e4fefd157 100644 --- a/processor/opentelemetry-processor-baggage/test-requirements.txt +++ b/processor/opentelemetry-processor-baggage/test-requirements.txt @@ -1,2 +1,7 @@ - --e processor/opentelemetry-processor-baggage \ No newline at end of file +importlib_metadata==8.0.0 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +pytest==7.4.4 +Deprecated==1.2.14 +-e processor/opentelemetry-processor-baggage From 35cc6f2854c419f912ef3d2fa2660573e8e277de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:43:13 -0300 Subject: [PATCH 123/335] add missing tests to urllib3 after semconv migration (#2748) --- .../tests/test_urllib3_integration.py | 101 +++++---- .../tests/test_urllib3_metrics.py | 195 ++++++++++++++---- 2 files changed, 205 insertions(+), 91 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py index 0e6037ed11..69bed0eaee 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py @@ -36,13 +36,6 @@ suppress_instrumentation, ) from opentelemetry.propagate import get_global_textmap, set_global_textmap -from opentelemetry.semconv.attributes.http_attributes import ( - HTTP_REQUEST_METHOD, - HTTP_REQUEST_METHOD_ORIGINAL, - HTTP_RESPONSE_STATUS_CODE, -) -from opentelemetry.semconv.attributes.url_attributes import URL_FULL -from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase from opentelemetry.trace import Span @@ -123,24 +116,29 @@ def assert_success_span( self.assertEqual( span.status.status_code, trace.status.StatusCode.UNSET ) - attr_old = { - SpanAttributes.HTTP_METHOD: "GET", - SpanAttributes.HTTP_URL: url, - SpanAttributes.HTTP_STATUS_CODE: 200, + expected_attr_old = { + "http.method": "GET", + "http.url": url, + "http.status_code": 200, } - attr_new = { - HTTP_REQUEST_METHOD: "GET", - URL_FULL: url, - HTTP_RESPONSE_STATUS_CODE: 200, + expected_attr_new = { + "http.request.method": "GET", + "url.full": url, + "http.response.status_code": 200, } attributes = { - _HTTPStabilityMode.DEFAULT: attr_old, - _HTTPStabilityMode.HTTP: attr_new, - _HTTPStabilityMode.HTTP_DUP: {**attr_new, **attr_old}, + _HTTPStabilityMode.DEFAULT: expected_attr_old, + _HTTPStabilityMode.HTTP: expected_attr_new, + _HTTPStabilityMode.HTTP_DUP: { + **expected_attr_new, + **expected_attr_old, + }, } - self.assertEqual(span.attributes, attributes.get(sem_conv_opt_in_mode)) + self.assertDictEqual( + dict(span.attributes), attributes.get(sem_conv_opt_in_mode) + ) def assert_exception_span( self, @@ -149,24 +147,29 @@ def assert_exception_span( ): span = self.assert_span() - attr_old = { - SpanAttributes.HTTP_METHOD: "GET", - SpanAttributes.HTTP_URL: url, + expected_attr_old = { + "http.method": "GET", + "http.url": url, } - attr_new = { - HTTP_REQUEST_METHOD: "GET", - URL_FULL: url, + expected_attr_new = { + "http.request.method": "GET", + "url.full": url, # TODO: Add `error.type` attribute when supported } attributes = { - _HTTPStabilityMode.DEFAULT: attr_old, - _HTTPStabilityMode.HTTP: attr_new, - _HTTPStabilityMode.HTTP_DUP: {**attr_new, **attr_old}, + _HTTPStabilityMode.DEFAULT: expected_attr_old, + _HTTPStabilityMode.HTTP: expected_attr_new, + _HTTPStabilityMode.HTTP_DUP: { + **expected_attr_new, + **expected_attr_old, + }, } - self.assertEqual(span.attributes, attributes.get(sem_conv_opt_in_mode)) + self.assertDictEqual( + dict(span.attributes), attributes.get(sem_conv_opt_in_mode) + ) self.assertEqual( trace.status.StatusCode.ERROR, span.status.status_code ) @@ -265,9 +268,7 @@ def test_basic_not_found(self): self.assertEqual(404, response.status) span = self.assert_span() - self.assertEqual( - 404, span.attributes.get(SpanAttributes.HTTP_STATUS_CODE) - ) + self.assertEqual(404, span.attributes.get("http.status_code")) self.assertIs(trace.status.StatusCode.ERROR, span.status.status_code) def test_basic_not_found_new_semconv(self): @@ -278,7 +279,7 @@ def test_basic_not_found_new_semconv(self): self.assertEqual(404, response.status) span = self.assert_span() - self.assertEqual(404, span.attributes.get(HTTP_RESPONSE_STATUS_CODE)) + self.assertEqual(404, span.attributes.get("http.response.status_code")) self.assertIs(trace.status.StatusCode.ERROR, span.status.status_code) def test_basic_not_found_both_semconv(self): @@ -289,10 +290,8 @@ def test_basic_not_found_both_semconv(self): self.assertEqual(404, response.status) span = self.assert_span() - self.assertEqual(404, span.attributes.get(HTTP_RESPONSE_STATUS_CODE)) - self.assertEqual( - 404, span.attributes.get(SpanAttributes.HTTP_STATUS_CODE) - ) + self.assertEqual(404, span.attributes.get("http.response.status_code")) + self.assertEqual(404, span.attributes.get("http.status_code")) self.assertIs(trace.status.StatusCode.ERROR, span.status.status_code) @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) @@ -303,12 +302,8 @@ def test_nonstandard_http_method(self): self.perform_request(self.HTTP_URL, method="NONSTANDARD") span = self.assert_span() self.assertEqual("HTTP", span.name) - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_METHOD), "_OTHER" - ) - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 405 - ) + self.assertEqual(span.attributes.get("http.method"), "_OTHER") + self.assertEqual(span.attributes.get("http.status_code"), 405) @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) def test_nonstandard_http_method_new_semconv(self): @@ -318,11 +313,11 @@ def test_nonstandard_http_method_new_semconv(self): self.perform_request(self.HTTP_URL, method="NONSTANDARD") span = self.assert_span() self.assertEqual("HTTP", span.name) - self.assertEqual(span.attributes.get(HTTP_REQUEST_METHOD), "_OTHER") + self.assertEqual(span.attributes.get("http.request.method"), "_OTHER") self.assertEqual( - span.attributes.get(HTTP_REQUEST_METHOD_ORIGINAL), "NONSTANDARD" + span.attributes.get("http.request.method_original"), "NONSTANDARD" ) - self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 405) + self.assertEqual(span.attributes.get("http.response.status_code"), 405) @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) def test_nonstandard_http_method_both_semconv(self): @@ -332,17 +327,13 @@ def test_nonstandard_http_method_both_semconv(self): self.perform_request(self.HTTP_URL, method="NONSTANDARD") span = self.assert_span() self.assertEqual("HTTP", span.name) + self.assertEqual(span.attributes.get("http.method"), "_OTHER") + self.assertEqual(span.attributes.get("http.status_code"), 405) + self.assertEqual(span.attributes.get("http.request.method"), "_OTHER") self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_METHOD), "_OTHER" - ) - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 405 - ) - self.assertEqual(span.attributes.get(HTTP_REQUEST_METHOD), "_OTHER") - self.assertEqual( - span.attributes.get(HTTP_REQUEST_METHOD_ORIGINAL), "NONSTANDARD" + span.attributes.get("http.request.method_original"), "NONSTANDARD" ) - self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 405) + self.assertEqual(span.attributes.get("http.response.status_code"), 405) def test_basic_http_non_default_port(self): url = "http://mock:666/status/200" diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py index c6e9011351..959f793398 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_metrics.py @@ -26,18 +26,6 @@ _OpenTelemetrySemanticConventionStability, ) from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor -from opentelemetry.semconv.attributes.http_attributes import ( - HTTP_REQUEST_METHOD, - HTTP_RESPONSE_STATUS_CODE, -) -from opentelemetry.semconv.attributes.network_attributes import ( - NETWORK_PROTOCOL_VERSION, -) -from opentelemetry.semconv.attributes.server_attributes import ( - SERVER_ADDRESS, - SERVER_PORT, -) -from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.httptest import HttpTestBase from opentelemetry.test.test_base import TestBase @@ -85,6 +73,7 @@ def test_basic_metrics(self): response = self.pool.request("GET", self.HTTP_URL) duration_ms = max(round((default_timer() - start_time) * 1000), 0) metrics = self.get_sorted_metrics() + self.assertEqual(len(metrics), 3) ( client_duration, @@ -93,13 +82,13 @@ def test_basic_metrics(self): ) = metrics attrs_old = { - SpanAttributes.HTTP_STATUS_CODE: 200, - SpanAttributes.HTTP_HOST: "mock", - SpanAttributes.NET_PEER_PORT: 80, - SpanAttributes.NET_PEER_NAME: "mock", - SpanAttributes.HTTP_METHOD: "GET", - SpanAttributes.HTTP_FLAVOR: "1.1", - SpanAttributes.HTTP_SCHEME: "http", + "http.status_code": 200, + "http.host": "mock", + "net.peer.port": 80, + "net.peer.name": "mock", + "http.method": "GET", + "http.flavor": "1.1", + "http.scheme": "http", } self.assertEqual(client_duration.name, "http.client.duration") @@ -154,6 +143,7 @@ def test_basic_metrics_new_semconv(self): duration_s = max(default_timer() - start_time, 0) metrics = self.get_sorted_metrics() + self.assertEqual(len(metrics), 3) ( client_request_size, client_duration, @@ -161,11 +151,11 @@ def test_basic_metrics_new_semconv(self): ) = metrics attrs_new = { - NETWORK_PROTOCOL_VERSION: "1.1", - SERVER_ADDRESS: "mock", - SERVER_PORT: 80, - HTTP_REQUEST_METHOD: "GET", - HTTP_RESPONSE_STATUS_CODE: 200, + "network.protocol.version": "1.1", + "server.address": "mock", + "server.port": 80, + "http.request.method": "GET", + "http.response.status_code": 200, # TODO: add URL_SCHEME to tests when supported in the implementation } @@ -217,6 +207,139 @@ def test_basic_metrics_new_semconv(self): ], ) + def test_basic_metrics_both_semconv(self): + start_time = default_timer() + response = self.pool.request("GET", self.HTTP_URL) + duration_s = max(default_timer() - start_time, 0) + duration = max(round(duration_s * 1000), 0) + expected_size = len(response.data) + + metrics = self.get_sorted_metrics() + self.assertEqual(len(metrics), 6) + + ( + client_duration, + client_request_body_size, + client_request_duration, + client_request_size, + client_response_body_size, + client_response_size, + ) = metrics[:6] + + attrs_new = { + "network.protocol.version": "1.1", + "server.address": "mock", + "server.port": 80, + "http.request.method": "GET", + "http.response.status_code": 200, + # TODO: add URL_SCHEME to tests when supported in the implementation + } + + attrs_old = { + "http.status_code": 200, + "http.host": "mock", + "net.peer.port": 80, + "net.peer.name": "mock", + "http.method": "GET", + "http.flavor": "1.1", + "http.scheme": "http", + } + + # assert new semconv metrics + self.assertEqual( + client_request_duration.name, "http.client.request.duration" + ) + self.assert_metric_expected( + client_request_duration, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=duration_s, + max_data_point=duration_s, + min_data_point=duration_s, + attributes=attrs_new, + ) + ], + est_value_delta=40 / 1000, + ) + + self.assertEqual( + client_request_body_size.name, "http.client.request.body.size" + ) + self.assert_metric_expected( + client_request_body_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=0, + max_data_point=0, + min_data_point=0, + attributes=attrs_new, + ) + ], + ) + + self.assertEqual( + client_response_body_size.name, "http.client.response.body.size" + ) + self.assert_metric_expected( + client_response_body_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=expected_size, + max_data_point=expected_size, + min_data_point=expected_size, + attributes=attrs_new, + ) + ], + ) + # assert old semconv metrics + self.assertEqual(client_duration.name, "http.client.duration") + self.assert_metric_expected( + client_duration, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=duration, + max_data_point=duration, + min_data_point=duration, + attributes=attrs_old, + ) + ], + est_value_delta=40, + ) + + self.assertEqual(client_request_size.name, "http.client.request.size") + self.assert_metric_expected( + client_request_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=0, + max_data_point=0, + min_data_point=0, + attributes=attrs_old, + ) + ], + ) + + self.assertEqual( + client_response_size.name, "http.client.response.size" + ) + self.assert_metric_expected( + client_response_size, + [ + self.create_histogram_data_point( + count=1, + sum_data_point=expected_size, + max_data_point=expected_size, + min_data_point=expected_size, + attributes=attrs_old, + ) + ], + ) + @mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",)) def test_basic_metrics_nonstandard_http_method(self): httpretty.register_uri( @@ -236,13 +359,13 @@ def test_basic_metrics_nonstandard_http_method(self): ) = metrics attrs_old = { - SpanAttributes.HTTP_STATUS_CODE: 405, - SpanAttributes.HTTP_HOST: "mock", - SpanAttributes.NET_PEER_PORT: 80, - SpanAttributes.NET_PEER_NAME: "mock", - SpanAttributes.HTTP_METHOD: "_OTHER", - SpanAttributes.HTTP_FLAVOR: "1.1", - SpanAttributes.HTTP_SCHEME: "http", + "http.status_code": 405, + "http.host": "mock", + "net.peer.port": 80, + "net.peer.name": "mock", + "http.method": "_OTHER", + "http.flavor": "1.1", + "http.scheme": "http", } self.assertEqual(client_duration.name, "http.client.duration") @@ -309,11 +432,11 @@ def test_basic_metrics_nonstandard_http_method_new_semconv(self): ) = metrics attrs_new = { - NETWORK_PROTOCOL_VERSION: "1.1", - SERVER_ADDRESS: "mock", - SERVER_PORT: 80, - HTTP_REQUEST_METHOD: "_OTHER", - HTTP_RESPONSE_STATUS_CODE: 405, + "network.protocol.version": "1.1", + "server.address": "mock", + "server.port": 80, + "http.request.method": "_OTHER", + "http.response.status_code": 405, "error.type": "405", # TODO: add URL_SCHEME to tests when supported in the implementation } From b65f67ded5f6990d163e05b697592dc602344d63 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 30 Jul 2024 09:55:28 -0700 Subject: [PATCH 124/335] Re-add `http.target` to Django old sem conv server duration metric (#2746) --- CHANGELOG.md | 5 + .../django/middleware/otel_middleware.py | 5 + .../tests/test_middleware.py | 301 +++++++++--------- .../instrumentation/flask/__init__.py | 1 + 4 files changed, 168 insertions(+), 144 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7924d9211e..0c1e2f596f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics + ([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746)) + ## Version 1.26.0/0.47b0 (2024-07-23) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 4530a16506..667d6f1091 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -333,6 +333,7 @@ def process_exception(self, request, exception): # pylint: disable=too-many-branches # pylint: disable=too-many-locals + # pylint: disable=too-many-statements def process_response(self, request, response): if self._excluded_urls.url_disabled(request.build_absolute_uri("?")): return response @@ -426,6 +427,10 @@ def process_response(self, request, response): duration_attrs_old = _parse_duration_attrs( duration_attrs, _HTTPStabilityMode.DEFAULT ) + # http.target to be included in old semantic conventions + target = duration_attrs.get(SpanAttributes.HTTP_TARGET) + if target: + duration_attrs_old[SpanAttributes.HTTP_TARGET] = target self._duration_histogram_old.record( max(round(duration_s * 1000), 0), duration_attrs_old ) diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index 1b9a904ce1..85ebbd747f 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -28,10 +28,6 @@ from opentelemetry.instrumentation._semconv import ( OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, - _server_active_requests_count_attrs_new, - _server_active_requests_count_attrs_old, - _server_duration_attrs_new, - _server_duration_attrs_old, ) from opentelemetry.instrumentation.django import ( DjangoInstrumentor, @@ -48,24 +44,6 @@ ) from opentelemetry.sdk.trace import Span from opentelemetry.sdk.trace.id_generator import RandomIdGenerator -from opentelemetry.semconv.attributes.client_attributes import CLIENT_ADDRESS -from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE -from opentelemetry.semconv.attributes.exception_attributes import ( - EXCEPTION_MESSAGE, - EXCEPTION_TYPE, -) -from opentelemetry.semconv.attributes.http_attributes import ( - HTTP_REQUEST_METHOD, - HTTP_REQUEST_METHOD_ORIGINAL, - HTTP_RESPONSE_STATUS_CODE, - HTTP_ROUTE, -) -from opentelemetry.semconv.attributes.network_attributes import ( - NETWORK_PROTOCOL_VERSION, -) -from opentelemetry.semconv.attributes.server_attributes import SERVER_PORT -from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME -from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.trace import ( SpanKind, @@ -197,18 +175,18 @@ def test_templated_route_get(self): ) self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual(span.attributes["http.method"], "GET") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/route/2020/template/", ) if DJANGO_2_2: self.assertEqual( - span.attributes[SpanAttributes.HTTP_ROUTE], + span.attributes["http.route"], "^route/(?P[0-9]{4})/template/$", ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 200) def test_traced_get(self): Client().get("/traced/") @@ -221,17 +199,15 @@ def test_traced_get(self): self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual(span.attributes["http.method"], "GET") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/traced/", ) if DJANGO_2_2: - self.assertEqual( - span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/" - ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 200) def test_traced_get_new_semconv(self): Client().get("/traced/") @@ -244,14 +220,14 @@ def test_traced_get_new_semconv(self): self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") - self.assertEqual(span.attributes[URL_SCHEME], "http") - self.assertEqual(span.attributes[SERVER_PORT], 80) - self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") - self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes["http.request.method"], "GET") + self.assertEqual(span.attributes["url.scheme"], "http") + self.assertEqual(span.attributes["server.port"], 80) + self.assertEqual(span.attributes["client.address"], "127.0.0.1") + self.assertEqual(span.attributes["network.protocol.version"], "1.1") if DJANGO_2_2: - self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") - self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.response.status_code"], 200) def test_traced_get_both_semconv(self): Client().get("/traced/") @@ -264,25 +240,23 @@ def test_traced_get_both_semconv(self): self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual(span.attributes["http.method"], "GET") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/traced/", ) if DJANGO_2_2: - self.assertEqual( - span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/" - ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") - self.assertEqual(span.attributes[URL_SCHEME], "http") - self.assertEqual(span.attributes[SERVER_PORT], 80) - self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") - self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 200) + self.assertEqual(span.attributes["http.request.method"], "GET") + self.assertEqual(span.attributes["url.scheme"], "http") + self.assertEqual(span.attributes["server.port"], 80) + self.assertEqual(span.attributes["client.address"], "127.0.0.1") + self.assertEqual(span.attributes["network.protocol.version"], "1.1") if DJANGO_2_2: - self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") - self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.response.status_code"], 200) def test_not_recording(self): mock_tracer = Mock() @@ -318,17 +292,15 @@ def test_traced_post(self): self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "POST") + self.assertEqual(span.attributes["http.method"], "POST") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/traced/", ) if DJANGO_2_2: - self.assertEqual( - span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/" - ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 200) def test_traced_post_new_semconv(self): Client().post("/traced/") @@ -341,14 +313,14 @@ def test_traced_post_new_semconv(self): self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST") - self.assertEqual(span.attributes[URL_SCHEME], "http") - self.assertEqual(span.attributes[SERVER_PORT], 80) - self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") - self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes["http.request.method"], "POST") + self.assertEqual(span.attributes["url.scheme"], "http") + self.assertEqual(span.attributes["server.port"], 80) + self.assertEqual(span.attributes["client.address"], "127.0.0.1") + self.assertEqual(span.attributes["network.protocol.version"], "1.1") if DJANGO_2_2: - self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") - self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.response.status_code"], 200) def test_traced_post_both_semconv(self): Client().post("/traced/") @@ -361,21 +333,21 @@ def test_traced_post_both_semconv(self): self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.UNSET) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "POST") + self.assertEqual(span.attributes["http.method"], "POST") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/traced/", ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200) - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST") - self.assertEqual(span.attributes[URL_SCHEME], "http") - self.assertEqual(span.attributes[SERVER_PORT], 80) - self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1") - self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1") + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 200) + self.assertEqual(span.attributes["http.request.method"], "POST") + self.assertEqual(span.attributes["url.scheme"], "http") + self.assertEqual(span.attributes["server.port"], 80) + self.assertEqual(span.attributes["client.address"], "127.0.0.1") + self.assertEqual(span.attributes["network.protocol.version"], "1.1") if DJANGO_2_2: - self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/") - self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200) + self.assertEqual(span.attributes["http.route"], "^traced/") + self.assertEqual(span.attributes["http.response.status_code"], 200) def test_error(self): with self.assertRaises(ValueError): @@ -389,27 +361,21 @@ def test_error(self): self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.ERROR) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual(span.attributes["http.method"], "GET") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/error/", ) if DJANGO_2_2: - self.assertEqual( - span.attributes[SpanAttributes.HTTP_ROUTE], "^error/" - ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500) + self.assertEqual(span.attributes["http.route"], "^error/") + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 500) self.assertEqual(len(span.events), 1) event = span.events[0] self.assertEqual(event.name, "exception") - self.assertEqual( - event.attributes[SpanAttributes.EXCEPTION_TYPE], "ValueError" - ) - self.assertEqual( - event.attributes[SpanAttributes.EXCEPTION_MESSAGE], "error" - ) + self.assertEqual(event.attributes["exception.type"], "ValueError") + self.assertEqual(event.attributes["exception.message"], "error") def test_error_new_semconv(self): with self.assertRaises(ValueError): @@ -423,18 +389,18 @@ def test_error_new_semconv(self): self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.ERROR) - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes["http.request.method"], "GET") if DJANGO_2_2: - self.assertEqual(span.attributes[HTTP_ROUTE], "^error/") - self.assertEqual(span.attributes[URL_SCHEME], "http") - self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500) + self.assertEqual(span.attributes["http.route"], "^error/") + self.assertEqual(span.attributes["url.scheme"], "http") + self.assertEqual(span.attributes["http.response.status_code"], 500) self.assertEqual(len(span.events), 1) event = span.events[0] self.assertEqual(event.name, "exception") - self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError") - self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error") - self.assertEqual(span.attributes[ERROR_TYPE], "500") + self.assertEqual(event.attributes["exception.type"], "ValueError") + self.assertEqual(event.attributes["exception.message"], "error") + self.assertEqual(span.attributes["error.type"], "500") def test_error_both_semconv(self): with self.assertRaises(ValueError): @@ -448,29 +414,27 @@ def test_error_both_semconv(self): self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET") self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual(span.status.status_code, StatusCode.ERROR) - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET") + self.assertEqual(span.attributes["http.method"], "GET") self.assertEqual( - span.attributes[SpanAttributes.HTTP_URL], + span.attributes["http.url"], "http://testserver/error/", ) if DJANGO_2_2: - self.assertEqual( - span.attributes[SpanAttributes.HTTP_ROUTE], "^error/" - ) - self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http") - self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500) - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET") + self.assertEqual(span.attributes["http.route"], "^error/") + self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 500) + self.assertEqual(span.attributes["http.request.method"], "GET") if DJANGO_2_2: - self.assertEqual(span.attributes[HTTP_ROUTE], "^error/") - self.assertEqual(span.attributes[URL_SCHEME], "http") - self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500) + self.assertEqual(span.attributes["http.route"], "^error/") + self.assertEqual(span.attributes["url.scheme"], "http") + self.assertEqual(span.attributes["http.response.status_code"], 500) self.assertEqual(len(span.events), 1) event = span.events[0] self.assertEqual(event.name, "exception") - self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError") - self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error") - self.assertEqual(span.attributes[ERROR_TYPE], "500") + self.assertEqual(event.attributes["exception.type"], "ValueError") + self.assertEqual(event.attributes["exception.message"], "error") + self.assertEqual(span.attributes["error.type"], "500") def test_exclude_lists(self): client = Client() @@ -545,7 +509,7 @@ def test_nonstandard_http_method_span_name(self): span = span_list[0] self.assertEqual(span.name, "HTTP") - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER") + self.assertEqual(span.attributes["http.method"], "_OTHER") def test_nonstandard_http_method_span_name_new_semconv(self): Client().request( @@ -556,9 +520,9 @@ def test_nonstandard_http_method_span_name_new_semconv(self): span = span_list[0] self.assertEqual(span.name, "HTTP") - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER") + self.assertEqual(span.attributes["http.request.method"], "_OTHER") self.assertEqual( - span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD" + span.attributes["http.request.method_original"], "NONSTANDARD" ) def test_nonstandard_http_method_span_name_both_semconv(self): @@ -570,10 +534,10 @@ def test_nonstandard_http_method_span_name_both_semconv(self): span = span_list[0] self.assertEqual(span.name, "HTTP") - self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER") - self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER") + self.assertEqual(span.attributes["http.method"], "_OTHER") + self.assertEqual(span.attributes["http.request.method"], "_OTHER") self.assertEqual( - span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD" + span.attributes["http.request.method_original"], "NONSTANDARD" ) def test_traced_request_attrs(self): @@ -711,9 +675,20 @@ def test_wsgi_metrics(self): "http.server.active_requests", "http.server.duration", ] - _recommended_attrs = { - "http.server.active_requests": _server_active_requests_count_attrs_old, - "http.server.duration": _server_duration_attrs_old, + expected_duration_attributes = { + "http.method": "GET", + "http.scheme": "http", + "http.flavor": "1.1", + "http.server_name": "testserver", + "net.host.port": 80, + "http.status_code": 200, + "http.target": "^span_name/([0-9]{4})/$", + } + expected_requests_count_attributes = { + "http.method": "GET", + "http.scheme": "http", + "http.flavor": "1.1", + "http.server_name": "testserver", } start = default_timer() for _ in range(3): @@ -740,12 +715,16 @@ def test_wsgi_metrics(self): self.assertAlmostEqual( duration, point.sum, delta=100 ) + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) if isinstance(point, NumberDataPoint): number_data_point_seen = True self.assertEqual(point.value, 0) - for attr in point.attributes: - self.assertIn( - attr, _recommended_attrs[metric.name] + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), ) self.assertTrue(histrogram_data_point_seen and number_data_point_seen) @@ -755,9 +734,16 @@ def test_wsgi_metrics_new_semconv(self): "http.server.active_requests", "http.server.request.duration", ] - _recommended_attrs = { - "http.server.active_requests": _server_active_requests_count_attrs_new, - "http.server.request.duration": _server_duration_attrs_new, + expected_duration_attributes = { + "http.request.method": "GET", + "url.scheme": "http", + "network.protocol.version": "1.1", + "http.response.status_code": 200, + "http.route": "^span_name/([0-9]{4})/$", + } + expected_requests_count_attributes = { + "http.request.method": "GET", + "url.scheme": "http", } start = default_timer() for _ in range(3): @@ -784,12 +770,16 @@ def test_wsgi_metrics_new_semconv(self): self.assertAlmostEqual( duration_s, point.sum, places=1 ) + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) if isinstance(point, NumberDataPoint): number_data_point_seen = True self.assertEqual(point.value, 0) - for attr in point.attributes: - self.assertIn( - attr, _recommended_attrs[metric.name] + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), ) self.assertTrue(histrogram_data_point_seen and number_data_point_seen) @@ -801,12 +791,29 @@ def test_wsgi_metrics_both_semconv(self): "http.server.active_requests", "http.server.request.duration", ] - active_count_both_attrs = list(_server_active_requests_count_attrs_new) - active_count_both_attrs.extend(_server_active_requests_count_attrs_old) - _recommended_attrs = { - "http.server.active_requests": active_count_both_attrs, - "http.server.request.duration": _server_duration_attrs_new, - "http.server.duration": _server_duration_attrs_old, + expected_duration_attributes_old = { + "http.method": "GET", + "http.scheme": "http", + "http.flavor": "1.1", + "http.server_name": "testserver", + "net.host.port": 80, + "http.status_code": 200, + "http.target": "^span_name/([0-9]{4})/$", + } + expected_duration_attributes_new = { + "http.request.method": "GET", + "url.scheme": "http", + "network.protocol.version": "1.1", + "http.response.status_code": 200, + "http.route": "^span_name/([0-9]{4})/$", + } + expected_requests_count_attributes = { + "http.method": "GET", + "http.scheme": "http", + "http.flavor": "1.1", + "http.server_name": "testserver", + "http.request.method": "GET", + "url.scheme": "http", } start = default_timer() for _ in range(3): @@ -835,16 +842,24 @@ def test_wsgi_metrics_both_semconv(self): self.assertAlmostEqual( duration_s, point.sum, places=1 ) + self.assertDictEqual( + expected_duration_attributes_new, + dict(point.attributes), + ) elif metric.name == "http.server.duration": self.assertAlmostEqual( duration, point.sum, delta=100 ) + self.assertDictEqual( + expected_duration_attributes_old, + dict(point.attributes), + ) if isinstance(point, NumberDataPoint): number_data_point_seen = True self.assertEqual(point.value, 0) - for attr in point.attributes: - self.assertIn( - attr, _recommended_attrs[metric.name] + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), ) self.assertTrue(histrogram_data_point_seen and number_data_point_seen) @@ -911,9 +926,7 @@ def test_django_with_wsgi_instrumented(self): Client().get("/span_name/1234/") span_list = self.exporter.get_finished_spans() print(span_list) - self.assertEqual( - span_list[0].attributes[SpanAttributes.HTTP_STATUS_CODE], 200 - ) + self.assertEqual(span_list[0].attributes["http.status_code"], 200) self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind) self.assertEqual( parent_span.get_span_context().span_id, 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 9bc5e85a12..0093715ae1 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -395,6 +395,7 @@ def _start_response(status, response_headers, *args, **kwargs): ) if request_route: + # http.target to be included in old semantic conventions duration_attrs_old[SpanAttributes.HTTP_TARGET] = str( request_route ) From 1c8d8ef5368c15d27c0973ce80787fd94c7b3176 Mon Sep 17 00:00:00 2001 From: Vamsi Kocherla <42316524+VamsiKrishna1211@users.noreply.github.com> Date: Tue, 30 Jul 2024 22:56:27 +0530 Subject: [PATCH 125/335] added conditional calling of `unary_unary` etc functions in `_InterceptorChannel` (#2484) --- CHANGELOG.md | 3 +- .../grpc/grpcext/_interceptor.py | 80 +++++++++++++++---- ...quirements.txt => test-requirements-0.txt} | 0 .../test-requirements-1.txt | 20 +++++ tox.ini | 12 ++- 5 files changed, 95 insertions(+), 20 deletions(-) rename instrumentation/opentelemetry-instrumentation-grpc/{test-requirements.txt => test-requirements-0.txt} (100%) create mode 100644 instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c1e2f596f..54452faf3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics ([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746)) +- `opentelemetry-instrumentation-grpc` Fixes the issue with the gRPC instrumentation not working with the 1.63.0 and higher version of gRPC + ([#2483](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2484)) ## Version 1.26.0/0.47b0 (2024-07-23) @@ -104,7 +106,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. ([#2627](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2627)) - ## Version 1.25.0/0.46b0 (2024-05-31) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py index 53ee46a20d..32cec6dee0 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py @@ -272,11 +272,23 @@ def unsubscribe(self, *args, **kwargs): self._channel.unsubscribe(*args, **kwargs) def unary_unary( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): - base_callable = self._channel.unary_unary( - method, request_serializer, response_deserializer - ) + if _registered_method: + base_callable = self._channel.unary_unary( + method, + request_serializer, + response_deserializer, + _registered_method, + ) + else: + base_callable = self._channel.unary_unary( + method, request_serializer, response_deserializer + ) if isinstance(self._interceptor, grpcext.UnaryClientInterceptor): return _InterceptorUnaryUnaryMultiCallable( method, base_callable, self._interceptor @@ -284,11 +296,23 @@ def unary_unary( return base_callable def unary_stream( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): - base_callable = self._channel.unary_stream( - method, request_serializer, response_deserializer - ) + if _registered_method: + base_callable = self._channel.unary_stream( + method, + request_serializer, + response_deserializer, + _registered_method, + ) + else: + base_callable = self._channel.unary_stream( + method, request_serializer, response_deserializer + ) if isinstance(self._interceptor, grpcext.StreamClientInterceptor): return _InterceptorUnaryStreamMultiCallable( method, base_callable, self._interceptor @@ -296,11 +320,23 @@ def unary_stream( return base_callable def stream_unary( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): - base_callable = self._channel.stream_unary( - method, request_serializer, response_deserializer - ) + if _registered_method: + base_callable = self._channel.stream_unary( + method, + request_serializer, + response_deserializer, + _registered_method, + ) + else: + base_callable = self._channel.stream_unary( + method, request_serializer, response_deserializer + ) if isinstance(self._interceptor, grpcext.StreamClientInterceptor): return _InterceptorStreamUnaryMultiCallable( method, base_callable, self._interceptor @@ -308,11 +344,23 @@ def stream_unary( return base_callable def stream_stream( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): - base_callable = self._channel.stream_stream( - method, request_serializer, response_deserializer - ) + if _registered_method: + base_callable = self._channel.stream_stream( + method, + request_serializer, + response_deserializer, + _registered_method, + ) + else: + base_callable = self._channel.stream_stream( + method, request_serializer, response_deserializer + ) if isinstance(self._interceptor, grpcext.StreamClientInterceptor): return _InterceptorStreamStreamMultiCallable( method, base_callable, self._interceptor diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt similarity index 100% rename from instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt rename to instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt new file mode 100644 index 0000000000..6d9531cd5e --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -0,0 +1,20 @@ +asgiref==3.7.2 +attrs==23.2.0 +Deprecated==1.2.14 +grpcio==1.63.0 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +packaging==23.2 +pluggy==1.4.0 +protobuf==3.20.3 +py==1.11.0 +py-cpuinfo==9.0.0 +pytest==7.1.3 +pytest-asyncio==0.23.5 +pytest-benchmark==4.0.0 +tomli==2.0.1 +typing_extensions==4.9.0 +wrapt==1.16.0 +zipp==3.17.0 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-grpc diff --git a/tox.ini b/tox.ini index 4ba434b29b..028db9c19f 100644 --- a/tox.ini +++ b/tox.ini @@ -247,8 +247,12 @@ envlist = lint-instrumentation-wsgi ; opentelemetry-instrumentation-grpc - py3{8,9,10,11,12}-test-instrumentation-grpc - pypy3-test-instrumentation-grpc + ; The numbers at the end of the environment names + ; below mean these dependencies are being used: + ; 0: grpcio==1.62.0 + ; 1: grpcio==1.63.0 + py3{8,9,10,11,12}-test-instrumentation-grpc-{0,1} + pypy3-test-instrumentation-grpc-{0,1} lint-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy @@ -446,7 +450,9 @@ commands_pre = grpc: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions grpc: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk grpc: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - grpc: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements.txt + grpc-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt + grpc-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt + lint-instrumentation-grpc: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt wsgi: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api wsgi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions From d563f8d841d3bc05c67c2e3827c7c6bfe56cb969 Mon Sep 17 00:00:00 2001 From: Ronald Date: Tue, 30 Jul 2024 14:53:08 -0300 Subject: [PATCH 126/335] refactor: avoid exception when lambda_handler envs not present in aws-lambda instrumentation (#2750) --- CHANGELOG.md | 4 +++- .../instrumentation/aws_lambda/__init__.py | 10 +++++++++- .../test_aws_lambda_instrumentation_manual.py | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54452faf3d..712aedb938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -### Fixed +## Fixed +- `opentelemetry-instrumentation-aws-lambda` Avoid exception when a handler is not present. + ([#2750](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2750)) - `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics ([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746)) - `opentelemetry-instrumentation-grpc` Fixes the issue with the gRPC instrumentation not working with the 1.63.0 and higher version of gRPC diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index c320c12bde..883296d85b 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -410,7 +410,7 @@ def _instrument(self, **kwargs): """Instruments Lambda Handlers on AWS Lambda. See more: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#instrumenting-aws-lambda + https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md Args: **kwargs: Optional arguments @@ -422,6 +422,14 @@ def _instrument(self, **kwargs): request. """ lambda_handler = os.environ.get(ORIG_HANDLER, os.environ.get(_HANDLER)) + if not lambda_handler: + logger.warning( + ( + "Could not find the ORIG_HANDLER or _HANDLER in the environment variables. ", + "This instrumentation requires the OpenTelemetry Lambda extension installed.", + ) + ) + return # pylint: disable=attribute-defined-outside-init ( self._wrapped_module_name, diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index 9f25524e43..00940547ea 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -495,6 +495,20 @@ def test_lambda_handles_handler_exception_with_api_gateway_proxy_event( exc_env_patch.stop() + def test_lambda_handles_should_do_nothing_when_environment_variables_not_present( + self, + ): + exc_env_patch = mock.patch.dict( + "os.environ", + {_HANDLER: ""}, + ) + exc_env_patch.start() + AwsLambdaInstrumentor().instrument() + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + exc_env_patch.stop() + def test_uninstrument(self): AwsLambdaInstrumentor().instrument() From c87ffd4a3595cffa087be08e6d82b302677bb965 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 30 Jul 2024 11:28:31 -0700 Subject: [PATCH 127/335] HTTP semantic convention stability migration for urllib (#2736) --- CHANGELOG.md | 4 + instrumentation/README.md | 2 +- .../instrumentation/urllib/__init__.py | 236 ++++++++++++++---- .../instrumentation/urllib/package.py | 2 + .../tests/test_metrics_instrumentation.py | 228 ++++++++++++++++- .../tests/test_urllib_integration.py | 164 +++++++++++- 6 files changed, 572 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 712aedb938..1b09c75064 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2715](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2715)) - `opentelemetry-instrumentation-django` Implement new semantic convention opt-in with stable http semantic conventions ([#2714](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2714)) +- `opentelemetry-instrumentation-urllib` Implement new semantic convention opt-in migration + ([#2736](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2736)) ### Breaking changes @@ -71,6 +73,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2682](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2682)) - Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `django` middleware ([#2714](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2714)) +- Populate `{method}` as `HTTP` on `_OTHER` methods from scope for `urllib` instrumentation + ([#2736](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2736)) - `opentelemetry-instrumentation-httpx`, `opentelemetry-instrumentation-aiohttp-client`, `opentelemetry-instrumentation-requests` Populate `{method}` as `HTTP` on `_OTHER` methods ([#2726](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2726)) diff --git a/instrumentation/README.md b/instrumentation/README.md index 555e0bcd2a..20438e0a12 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -45,6 +45,6 @@ | [opentelemetry-instrumentation-threading](./opentelemetry-instrumentation-threading) | threading | No | experimental | [opentelemetry-instrumentation-tornado](./opentelemetry-instrumentation-tornado) | tornado >= 5.1.1 | Yes | experimental | [opentelemetry-instrumentation-tortoiseorm](./opentelemetry-instrumentation-tortoiseorm) | tortoise-orm >= 0.17.0 | No | experimental -| [opentelemetry-instrumentation-urllib](./opentelemetry-instrumentation-urllib) | urllib | Yes | experimental +| [opentelemetry-instrumentation-urllib](./opentelemetry-instrumentation-urllib) | urllib | Yes | migration | [opentelemetry-instrumentation-urllib3](./opentelemetry-instrumentation-urllib3) | urllib3 >= 1.0.0, < 3.0.0 | Yes | migration | [opentelemetry-instrumentation-wsgi](./opentelemetry-instrumentation-wsgi) | wsgi | Yes | migration \ No newline at end of file diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index befc022b35..d9072ba727 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -85,25 +85,49 @@ def response_hook(span, request_obj, response) Request, ) +from opentelemetry.instrumentation._semconv import ( + _client_duration_attrs_new, + _client_duration_attrs_old, + _filter_semconv_duration_attrs, + _get_schema_url, + _HTTPStabilityMode, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _report_old, + _set_http_method, + _set_http_network_protocol_version, + _set_http_url, + _set_status, +) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.urllib.package import _instruments from opentelemetry.instrumentation.urllib.version import __version__ from opentelemetry.instrumentation.utils import ( - http_status_to_status_code, is_http_instrumentation_enabled, suppress_http_instrumentation, ) from opentelemetry.metrics import Histogram, get_meter from opentelemetry.propagate import inject +from opentelemetry.semconv._incubating.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_BODY_SIZE, + HTTP_CLIENT_RESPONSE_BODY_SIZE, + create_http_client_request_body_size, + create_http_client_response_body_size, +) +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_DURATION, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import Span, SpanKind, get_tracer -from opentelemetry.trace.status import Status from opentelemetry.util.http import ( ExcludeList, get_excluded_urls, parse_excluded_urls, remove_url_credentials, + sanitize_method, ) _excluded_urls_from_env = get_excluded_urls("URLLIB") @@ -133,12 +157,18 @@ def _instrument(self, **kwargs): ``excluded_urls``: A string containing a comma-delimited list of regexes used to exclude URLs from tracking """ + # initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + schema_url = _get_schema_url(sem_conv_opt_in_mode) tracer_provider = kwargs.get("tracer_provider") tracer = get_tracer( __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=schema_url, ) excluded_urls = kwargs.get("excluded_urls") meter_provider = kwargs.get("meter_provider") @@ -146,10 +176,10 @@ def _instrument(self, **kwargs): __name__, __version__, meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=schema_url, ) - histograms = _create_client_histograms(meter) + histograms = _create_client_histograms(meter, sem_conv_opt_in_mode) _instrument( tracer, @@ -161,6 +191,7 @@ def _instrument(self, **kwargs): if excluded_urls is None else parse_excluded_urls(excluded_urls) ), + sem_conv_opt_in_mode=sem_conv_opt_in_mode, ) def _uninstrument(self, **kwargs): @@ -173,12 +204,14 @@ def uninstrument_opener( _uninstrument_from(opener, restore_as_bound_func=True) +# pylint: disable=too-many-statements def _instrument( tracer, histograms: Dict[str, Histogram], request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, excluded_urls: ExcludeList = None, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ): """Enables tracing of all requests calls that go through :code:`urllib.Client._make_request`""" @@ -214,14 +247,22 @@ def _instrumented_open_call( method = request.get_method().upper() - span_name = method.strip() + span_name = _get_span_name(method) url = remove_url_credentials(url) - labels = { - SpanAttributes.HTTP_METHOD: method, - SpanAttributes.HTTP_URL: url, - } + data = getattr(request, "data", None) + request_size = 0 if data is None else len(data) + + labels = {} + + _set_http_method( + labels, + method, + sanitize_method(method), + sem_conv_opt_in_mode, + ) + _set_http_url(labels, url, sem_conv_opt_in_mode) with tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=labels @@ -241,24 +282,50 @@ def _instrumented_open_call( exception = exc result = getattr(exc, "file", None) finally: - elapsed_time = round((default_timer() - start_time) * 1000) - + duration_s = default_timer() - start_time + response_size = 0 if result is not None: + response_size = int(result.headers.get("Content-Length", 0)) code_ = result.getcode() - labels[SpanAttributes.HTTP_STATUS_CODE] = str(code_) - - if span.is_recording() and code_ is not None: - span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, code_) - span.set_status(Status(http_status_to_status_code(code_))) + # set http status code based on semconv + if code_: + _set_status_code_attribute( + span, code_, labels, sem_conv_opt_in_mode + ) ver_ = str(getattr(result, "version", "")) if ver_: - labels[SpanAttributes.HTTP_FLAVOR] = ( - f"{ver_[:1]}.{ver_[:-1]}" + _set_http_network_protocol_version( + labels, f"{ver_[:1]}.{ver_[:-1]}", sem_conv_opt_in_mode ) + if exception is not None and _report_new(sem_conv_opt_in_mode): + span.set_attribute(ERROR_TYPE, type(exception).__qualname__) + labels[ERROR_TYPE] = type(exception).__qualname__ + + duration_attrs_old = _filter_semconv_duration_attrs( + labels, + _client_duration_attrs_old, + _client_duration_attrs_new, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + ) + duration_attrs_new = _filter_semconv_duration_attrs( + labels, + _client_duration_attrs_old, + _client_duration_attrs_new, + sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, + ) + + duration_attrs_old[SpanAttributes.HTTP_URL] = url + _record_histograms( - histograms, labels, request, result, elapsed_time + histograms, + duration_attrs_old, + duration_attrs_new, + request_size, + response_size, + duration_s, + sem_conv_opt_in_mode, ) if callable(response_hook): @@ -296,43 +363,108 @@ def _uninstrument_from(instr_root, restore_as_bound_func=False): setattr(instr_root, instr_func_name, original) -def _create_client_histograms(meter) -> Dict[str, Histogram]: - histograms = { - MetricInstruments.HTTP_CLIENT_DURATION: meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_DURATION, - unit="ms", - description="Measures the duration of outbound HTTP requests.", - ), - MetricInstruments.HTTP_CLIENT_REQUEST_SIZE: meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_REQUEST_SIZE, - unit="By", - description="Measures the size of HTTP request messages.", - ), - MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE: meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE, - unit="By", - description="Measures the size of HTTP response messages.", - ), - } +def _get_span_name(method: str) -> str: + method = sanitize_method(method.strip()) + if method == "_OTHER": + method = "HTTP" + return method + + +def _set_status_code_attribute( + span: Span, + status_code: int, + metric_attributes: dict = None, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, +) -> None: + + status_code_str = str(status_code) + try: + status_code = int(status_code) + except ValueError: + status_code = -1 + + if metric_attributes is None: + metric_attributes = {} + + _set_status( + span, + metric_attributes, + status_code, + status_code_str, + server_span=False, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + ) + + +def _create_client_histograms( + meter, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +) -> Dict[str, Histogram]: + histograms = {} + if _report_old(sem_conv_opt_in_mode): + histograms[MetricInstruments.HTTP_CLIENT_DURATION] = ( + meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_DURATION, + unit="ms", + description="Measures the duration of the outbound HTTP request", + ) + ) + histograms[MetricInstruments.HTTP_CLIENT_REQUEST_SIZE] = ( + meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_REQUEST_SIZE, + unit="By", + description="Measures the size of HTTP request messages.", + ) + ) + histograms[MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE] = ( + meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE, + unit="By", + description="Measures the size of HTTP response messages.", + ) + ) + if _report_new(sem_conv_opt_in_mode): + histograms[HTTP_CLIENT_REQUEST_DURATION] = meter.create_histogram( + name=HTTP_CLIENT_REQUEST_DURATION, + unit="s", + description="Duration of HTTP client requests.", + ) + histograms[HTTP_CLIENT_REQUEST_BODY_SIZE] = ( + create_http_client_request_body_size(meter) + ) + histograms[HTTP_CLIENT_RESPONSE_BODY_SIZE] = ( + create_http_client_response_body_size(meter) + ) return histograms def _record_histograms( - histograms, metric_attributes, request, response, elapsed_time + histograms: Dict[str, Histogram], + metric_attributes_old: dict, + metric_attributes_new: dict, + request_size: int, + response_size: int, + duration_s: float, + sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ): - histograms[MetricInstruments.HTTP_CLIENT_DURATION].record( - elapsed_time, attributes=metric_attributes - ) - - data = getattr(request, "data", None) - request_size = 0 if data is None else len(data) - histograms[MetricInstruments.HTTP_CLIENT_REQUEST_SIZE].record( - request_size, attributes=metric_attributes - ) - - if response is not None: - response_size = int(response.headers.get("Content-Length", 0)) + if _report_old(sem_conv_opt_in_mode): + duration = max(round(duration_s * 1000), 0) + histograms[MetricInstruments.HTTP_CLIENT_DURATION].record( + duration, attributes=metric_attributes_old + ) + histograms[MetricInstruments.HTTP_CLIENT_REQUEST_SIZE].record( + request_size, attributes=metric_attributes_old + ) histograms[MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE].record( - response_size, attributes=metric_attributes + response_size, attributes=metric_attributes_old + ) + if _report_new(sem_conv_opt_in_mode): + histograms[HTTP_CLIENT_REQUEST_DURATION].record( + duration_s, attributes=metric_attributes_new + ) + histograms[HTTP_CLIENT_REQUEST_BODY_SIZE].record( + request_size, attributes=metric_attributes_new + ) + histograms[HTTP_CLIENT_RESPONSE_BODY_SIZE].record( + response_size, attributes=metric_attributes_new ) diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py index 942f175da1..1bb8350a06 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py @@ -16,3 +16,5 @@ _instruments = tuple() _supports_metrics = True + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py index f79749dfd8..7a9bfd38f1 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py @@ -15,16 +15,28 @@ from platform import python_implementation from timeit import default_timer +from unittest.mock import patch from urllib import request from urllib.parse import urlencode import httpretty from pytest import mark +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.urllib import ( # pylint: disable=no-name-in-module,import-error URLLibInstrumentor, ) +from opentelemetry.semconv._incubating.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_BODY_SIZE, + HTTP_CLIENT_RESPONSE_BODY_SIZE, +) from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_DURATION, +) from opentelemetry.test.test_base import TestBase @@ -34,6 +46,23 @@ class TestUrllibMetricsInstrumentation(TestBase): def setUp(self): super().setUp() + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + + self.env_patch = patch.dict( + "os.environ", + { + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, + }, + ) + _OpenTelemetrySemanticConventionStability._initialized = False + self.env_patch.start() URLLibInstrumentor().instrument() httpretty.enable() httpretty.register_uri(httpretty.GET, self.URL, body=b"Hello!") @@ -71,18 +100,19 @@ def test_basic_metric(self): self.assertEqual( client_duration.name, MetricInstruments.HTTP_CLIENT_DURATION ) + self.assert_metric_expected( client_duration, self.create_histogram_data_points( client_duration_estimated, attributes={ - "http.status_code": str(result.code), + "http.status_code": int(result.code), "http.method": "GET", "http.url": str(result.url), "http.flavor": "1.1", }, ), - est_value_delta=200, + est_value_delta=40, ) self.assertEqual( @@ -94,7 +124,7 @@ def test_basic_metric(self): self.create_histogram_data_points( 0, attributes={ - "http.status_code": str(result.code), + "http.status_code": int(result.code), "http.method": "GET", "http.url": str(result.url), "http.flavor": "1.1", @@ -111,7 +141,7 @@ def test_basic_metric(self): self.create_histogram_data_points( result.length, attributes={ - "http.status_code": str(result.code), + "http.status_code": int(result.code), "http.method": "GET", "http.url": str(result.url), "http.flavor": "1.1", @@ -119,6 +149,188 @@ def test_basic_metric(self): ), ) + def test_basic_metric_new_semconv(self): + start_time = default_timer() + with request.urlopen(self.URL) as result: + duration_s = default_timer() - start_time + + metrics = self.get_sorted_metrics() + self.assertEqual(len(metrics), 3) + + ( + client_request_body_size, + client_request_duration, + client_response_body_size, + ) = metrics[:3] + + self.assertEqual( + client_request_duration.name, HTTP_CLIENT_REQUEST_DURATION + ) + + self.assert_metric_expected( + client_request_duration, + self.create_histogram_data_points( + duration_s, + attributes={ + "http.response.status_code": int(result.code), + "http.request.method": "GET", + "network.protocol.version": "1.1", + }, + ), + est_value_delta=40, + ) + + self.assertEqual( + client_request_body_size.name, + HTTP_CLIENT_REQUEST_BODY_SIZE, + ) + self.assert_metric_expected( + client_request_body_size, + self.create_histogram_data_points( + 0, + attributes={ + "http.response.status_code": int(result.code), + "http.request.method": "GET", + "network.protocol.version": "1.1", + }, + ), + ) + + self.assertEqual( + client_response_body_size.name, + HTTP_CLIENT_RESPONSE_BODY_SIZE, + ) + self.assert_metric_expected( + client_response_body_size, + self.create_histogram_data_points( + result.length, + attributes={ + "http.response.status_code": int(result.code), + "http.request.method": "GET", + "network.protocol.version": "1.1", + }, + ), + ) + + def test_basic_metric_both_semconv(self): + start_time = default_timer() + with request.urlopen(self.URL) as result: + duration_s = default_timer() - start_time + duration = max(round(duration_s * 1000), 0) + + metrics = self.get_sorted_metrics() + self.assertEqual(len(metrics), 6) + + ( + client_duration, + client_request_body_size, + client_request_duration, + client_request_size, + client_response_body_size, + client_response_size, + ) = metrics[:6] + + self.assertEqual( + client_duration.name, MetricInstruments.HTTP_CLIENT_DURATION + ) + + self.assert_metric_expected( + client_duration, + self.create_histogram_data_points( + duration, + attributes={ + "http.status_code": int(result.code), + "http.method": "GET", + "http.url": str(result.url), + "http.flavor": "1.1", + }, + ), + est_value_delta=40, + ) + + self.assertEqual( + client_request_size.name, + MetricInstruments.HTTP_CLIENT_REQUEST_SIZE, + ) + self.assert_metric_expected( + client_request_size, + self.create_histogram_data_points( + 0, + attributes={ + "http.status_code": int(result.code), + "http.method": "GET", + "http.url": str(result.url), + "http.flavor": "1.1", + }, + ), + ) + + self.assertEqual( + client_response_size.name, + MetricInstruments.HTTP_CLIENT_RESPONSE_SIZE, + ) + self.assert_metric_expected( + client_response_size, + self.create_histogram_data_points( + result.length, + attributes={ + "http.status_code": int(result.code), + "http.method": "GET", + "http.url": str(result.url), + "http.flavor": "1.1", + }, + ), + ) + + self.assertEqual( + client_request_duration.name, HTTP_CLIENT_REQUEST_DURATION + ) + + self.assert_metric_expected( + client_request_duration, + self.create_histogram_data_points( + duration_s, + attributes={ + "http.response.status_code": int(result.code), + "http.request.method": "GET", + "network.protocol.version": "1.1", + }, + ), + est_value_delta=40, + ) + + self.assertEqual( + client_request_body_size.name, + HTTP_CLIENT_REQUEST_BODY_SIZE, + ) + self.assert_metric_expected( + client_request_body_size, + self.create_histogram_data_points( + 0, + attributes={ + "http.response.status_code": int(result.code), + "http.request.method": "GET", + "network.protocol.version": "1.1", + }, + ), + ) + + self.assertEqual( + client_response_body_size.name, + HTTP_CLIENT_RESPONSE_BODY_SIZE, + ) + self.assert_metric_expected( + client_response_body_size, + self.create_histogram_data_points( + result.length, + attributes={ + "http.response.status_code": int(result.code), + "http.request.method": "GET", + "network.protocol.version": "1.1", + }, + ), + ) + def test_basic_metric_request_not_empty(self): data = {"header1": "value1", "header2": "value2"} data_encoded = urlencode(data).encode() @@ -144,13 +356,13 @@ def test_basic_metric_request_not_empty(self): self.create_histogram_data_points( client_duration_estimated, attributes={ - "http.status_code": str(result.code), + "http.status_code": int(result.code), "http.method": "POST", "http.url": str(result.url), "http.flavor": "1.1", }, ), - est_value_delta=200, + est_value_delta=40, ) self.assertEqual( @@ -162,7 +374,7 @@ def test_basic_metric_request_not_empty(self): self.create_histogram_data_points( len(data_encoded), attributes={ - "http.status_code": str(result.code), + "http.status_code": int(result.code), "http.method": "POST", "http.url": str(result.url), "http.flavor": "1.1", @@ -179,7 +391,7 @@ def test_basic_metric_request_not_empty(self): self.create_histogram_data_points( result.length, attributes={ - "http.status_code": str(result.code), + "http.status_code": int(result.code), "http.method": "POST", "http.url": str(result.url), "http.flavor": "1.1", diff --git a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py index f73f0d1b97..8ac0284939 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py @@ -25,6 +25,10 @@ import opentelemetry.instrumentation.urllib # pylint: disable=no-name-in-module,import-error from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.urllib import ( # pylint: disable=no-name-in-module,import-error URLLibInstrumentor, ) @@ -34,6 +38,12 @@ ) from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.sdk import resources +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.url_attributes import URL_FULL from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase @@ -43,7 +53,7 @@ # pylint: disable=too-many-public-methods -class RequestsIntegrationTestBase(abc.ABC): +class URLLibIntegrationTestBase(abc.ABC): # pylint: disable=no-member URL = "http://mock/status/200" @@ -54,12 +64,23 @@ class RequestsIntegrationTestBase(abc.ABC): def setUp(self): super().setUp() + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + self.env_patch = mock.patch.dict( "os.environ", { - "OTEL_PYTHON_URLLIB_EXCLUDED_URLS": "http://localhost/env_excluded_arg/123,env_excluded_noarg" + "OTEL_PYTHON_URLLIB_EXCLUDED_URLS": "http://localhost/env_excluded_arg/123,env_excluded_noarg", + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) + _OpenTelemetrySemanticConventionStability._initialized = False self.env_patch.start() self.exclude_patch = mock.patch( @@ -141,6 +162,57 @@ def test_basic(self): span, opentelemetry.instrumentation.urllib ) + def test_basic_new_semconv(self): + result = self.perform_request(self.URL) + + self.assertEqual(result.read(), b"Hello!") + span = self.assert_span() + + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "GET") + + self.assertEqual( + span.attributes, + { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: self.URL, + HTTP_RESPONSE_STATUS_CODE: 200, + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.UNSET) + + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.urllib + ) + + def test_basic_both_semconv(self): + result = self.perform_request(self.URL) + + self.assertEqual(result.read(), b"Hello!") + span = self.assert_span() + + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertEqual(span.name, "GET") + + self.assertEqual( + span.attributes, + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_URL: self.URL, + SpanAttributes.HTTP_STATUS_CODE: 200, + HTTP_REQUEST_METHOD: "GET", + URL_FULL: self.URL, + HTTP_RESPONSE_STATUS_CODE: 200, + }, + ) + + self.assertIs(span.status.status_code, trace.StatusCode.UNSET) + + self.assertEqualSpanInstrumentationInfo( + span, opentelemetry.instrumentation.urllib + ) + def test_excluded_urls_explicit(self): url_201 = "http://mock/status/201" httpretty.register_uri( @@ -197,6 +269,57 @@ def test_not_foundbasic(self): trace.StatusCode.ERROR, ) + def test_not_foundbasic_new_semconv(self): + url_404 = "http://mock/status/404/" + httpretty.register_uri( + httpretty.GET, + url_404, + status=404, + ) + exception = None + try: + self.perform_request(url_404) + except Exception as err: # pylint: disable=broad-except + exception = err + code = exception.code + self.assertEqual(code, 404) + + span = self.assert_span() + + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404) + + self.assertIs( + span.status.status_code, + trace.StatusCode.ERROR, + ) + + def test_not_foundbasic_both_semconv(self): + url_404 = "http://mock/status/404/" + httpretty.register_uri( + httpretty.GET, + url_404, + status=404, + ) + exception = None + try: + self.perform_request(url_404) + except Exception as err: # pylint: disable=broad-except + exception = err + code = exception.code + self.assertEqual(code, 404) + + span = self.assert_span() + + self.assertEqual( + span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 404 + ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404) + + self.assertIs( + span.status.status_code, + trace.StatusCode.ERROR, + ) + @staticmethod def mock_get_code(*args, **kwargs): return None @@ -339,6 +462,41 @@ def test_requests_exception_with_response(self, *_, **__): ) self.assertEqual(span.status.status_code, StatusCode.ERROR) + def test_requests_exception_with_response_new_semconv(self, *_, **__): + with self.assertRaises(HTTPError): + self.perform_request("http://mock/status/500") + + span = self.assert_span() + self.assertEqual( + dict(span.attributes), + { + HTTP_REQUEST_METHOD: "GET", + URL_FULL: "http://mock/status/500", + HTTP_RESPONSE_STATUS_CODE: 500, + ERROR_TYPE: "HTTPError", + }, + ) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + + def test_requests_exception_with_response_both_semconv(self, *_, **__): + with self.assertRaises(HTTPError): + self.perform_request("http://mock/status/500") + + span = self.assert_span() + self.assertEqual( + dict(span.attributes), + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_URL: "http://mock/status/500", + SpanAttributes.HTTP_STATUS_CODE: 500, + HTTP_REQUEST_METHOD: "GET", + URL_FULL: "http://mock/status/500", + HTTP_RESPONSE_STATUS_CODE: 500, + ERROR_TYPE: "HTTPError", + }, + ) + self.assertEqual(span.status.status_code, StatusCode.ERROR) + def test_requests_basic_exception(self, *_, **__): with self.assertRaises(Exception): self.perform_request(self.URL_EXCEPTION) @@ -393,7 +551,7 @@ def test_no_op_tracer_provider(self): self.assert_span(num_spans=0) -class TestRequestsIntegration(RequestsIntegrationTestBase, TestBase): +class TestURLLibIntegration(URLLibIntegrationTestBase, TestBase): @staticmethod def perform_request(url: str, opener: OpenerDirector = None): if not opener: From bfcb16b3c074eae2612847534eb7460a442135a0 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 30 Jul 2024 14:23:35 -0600 Subject: [PATCH 128/335] Update CORE_REPO_SHA (#2755) Fixes #2754 --- .github/workflows/instrumentations_0.yml | 2 +- .github/workflows/instrumentations_1.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml index 972a33532c..382284d204 100644 --- a/.github/workflows/instrumentations_0.yml +++ b/.github/workflows/instrumentations_0.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 + CORE_REPO_SHA: main jobs: instrumentations-0: diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 48d0839f81..40689bdc13 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 + CORE_REPO_SHA: main jobs: instrumentations-1: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0e2dc7110d..b9f7a41c17 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 + CORE_REPO_SHA: main jobs: lint-3_12: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d749788204..2714942c21 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: f31903a03721ce90c338be33131222d4cba37325 + CORE_REPO_SHA: main jobs: misc: From dab664c06ece93eac75c81aa84d5666887d17a1a Mon Sep 17 00:00:00 2001 From: Omar Abdelkader Date: Wed, 31 Jul 2024 13:20:08 -0400 Subject: [PATCH 129/335] feat(mysql): add support for mysql-connector-python v9 (#2751) --- CHANGELOG.md | 1 + instrumentation/README.md | 2 +- .../pyproject.toml | 2 +- .../instrumentation/mysql/package.py | 2 +- ...-requirements.txt => test-requirements-0.txt} | 0 .../test-requirements-1.txt | 16 ++++++++++++++++ .../instrumentation/bootstrap_gen.py | 2 +- tox.ini | 12 +++++++++--- 8 files changed, 30 insertions(+), 7 deletions(-) rename instrumentation/opentelemetry-instrumentation-mysql/{test-requirements.txt => test-requirements-0.txt} (100%) create mode 100644 instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b09c75064..0d1f17c43e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) - `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. ([#2627](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2627)) +- `opentelemetry-instrumentation-mysql` Add support for `mysql-connector-python` v9 ([#2751](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2751)) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/README.md b/instrumentation/README.md index 20438e0a12..278182e61f 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -26,7 +26,7 @@ | [opentelemetry-instrumentation-jinja2](./opentelemetry-instrumentation-jinja2) | jinja2 >= 2.7, < 4.0 | No | experimental | [opentelemetry-instrumentation-kafka-python](./opentelemetry-instrumentation-kafka-python) | kafka-python >= 2.0 | No | experimental | [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging | No | experimental -| [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python ~= 8.0 | No | experimental +| [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python >= 8.0, < 10.0 | No | experimental | [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | experimental | [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 | No | experimental | [opentelemetry-instrumentation-psycopg](./opentelemetry-instrumentation-psycopg) | psycopg >= 3.1.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index cb1c51b082..3c7d0c9166 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "mysql-connector-python ~= 8.0", + "mysql-connector-python >= 8.0, < 10.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/package.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/package.py index efb8ece73b..4d84c1161b 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/package.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/package.py @@ -13,4 +13,4 @@ # limitations under the License. -_instruments = ("mysql-connector-python ~= 8.0",) +_instruments = ("mysql-connector-python >= 8.0, < 10.0",) diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt similarity index 100% rename from instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt rename to instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt new file mode 100644 index 0000000000..dd609e594a --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt @@ -0,0 +1,16 @@ +asgiref==3.7.2 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +mysql-connector-python==9.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +tomli==2.0.1 +typing_extensions==4.9.0 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-dbapi +-e instrumentation/opentelemetry-instrumentation-mysql diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 4ad6824281..0deb99b8bf 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -109,7 +109,7 @@ "instrumentation": "opentelemetry-instrumentation-kafka-python==0.48b0.dev", }, { - "library": "mysql-connector-python ~= 8.0", + "library": "mysql-connector-python >= 8.0, < 10.0", "instrumentation": "opentelemetry-instrumentation-mysql==0.48b0.dev", }, { diff --git a/tox.ini b/tox.ini index 028db9c19f..5e433d5bb4 100644 --- a/tox.ini +++ b/tox.ini @@ -177,8 +177,12 @@ envlist = lint-exporter-prometheus-remote-write ; opentelemetry-instrumentation-mysql - py3{8,9,10,11,12}-test-instrumentation-mysql - pypy3-test-instrumentation-mysql + ; The numbers at the end of the environment names + ; below mean these dependencies are being used: + ; 0: mysql-connector-python >=8.0.0,<9.0.0 + ; 1: mysql-connector-python ~=9.0.0 + py3{8,9,10,11,12}-test-instrumentation-mysql-{0,1} + pypy3-test-instrumentation-mysql-{0,1} lint-instrumentation-mysql ; opentelemetry-instrumentation-mysqlclient @@ -562,7 +566,9 @@ commands_pre = mysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions mysql: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk mysql: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - mysql: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements.txt + mysql-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt + mysql-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt + lint-instrumentation-mysql: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt mysqlclient: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api mysqlclient: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions From 32e6f6da92c8f4b137e6fc9c6cdb07c66c6cec86 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 1 Aug 2024 20:56:41 +0200 Subject: [PATCH 130/335] instrumentation/fastapi: fix fastapi-slim support (#2756) --- .github/workflows/instrumentations_1.yml | 2 +- CHANGELOG.md | 2 ++ .../instrumentation/fastapi/__init__.py | 18 ++++++++++++++---- tox.ini | 14 +++++++------- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 40689bdc13..2658f4d4b2 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -38,7 +38,7 @@ jobs: - "resource-detector-azure" - "resource-detector-container" - "util-http" - - "fastapi-slim" + - "fastapislim" - "processor-baggage" os: [ubuntu-20.04] exclude: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d1f17c43e..a47bb6fe0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746)) - `opentelemetry-instrumentation-grpc` Fixes the issue with the gRPC instrumentation not working with the 1.63.0 and higher version of gRPC ([#2483](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2484)) +- `opentelemetry-instrumentation-fastapi` Fix fastapi-slim support + ([#2756](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2756)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 9356093a45..bfb4f4a682 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -172,7 +172,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A --- """ import logging -from importlib.util import find_spec +from importlib.metadata import PackageNotFoundError, distribution from typing import Collection import fastapi @@ -285,10 +285,20 @@ def uninstrument_app(app: fastapi.FastAPI): app._is_instrumented_by_opentelemetry = False def instrumentation_dependencies(self) -> Collection[str]: - if find_spec("fastapi") is not None: - return (_fastapi,) - if find_spec("fastapi_slim") is not None: + # need to use distribution because find_spec("fastapi") will return + # something even with just fastapi-slim installed + try: + distribution("fastapi-slim") return (_fastapi_slim,) + except PackageNotFoundError: + pass + + try: + distribution("fastapi") + return (_fastapi,) + except PackageNotFoundError: + pass + # If neither is installed, return both as potential dependencies return _instruments diff --git a/tox.ini b/tox.ini index 5e433d5bb4..27eaaa9129 100644 --- a/tox.ini +++ b/tox.ini @@ -116,9 +116,9 @@ envlist = ; opentelemetry-instrumentation-fastapi py3{8,9,10,11,12}-test-instrumentation-fastapi - py3{8,9,10,11,12}-test-instrumentation-fastapi-slim + py3{8,9,10,11,12}-test-instrumentation-fastapislim pypy3-test-instrumentation-fastapi - pypy3-test-instrumentation-fastapi-slim + pypy3-test-instrumentation-fastapislim lint-instrumentation-fastapi ; opentelemetry-instrumentation-flask @@ -556,11 +556,11 @@ commands_pre = fastapi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk fastapi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt - fastapi-slim: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - fastapi-slim: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - fastapi-slim: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - fastapi-slim: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - fastapi-slim: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt + fastapislim: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + fastapislim: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + fastapislim: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + fastapislim: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + fastapislim: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt mysql: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api mysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions From fa6a36b8ef7f7935734a05fe0bcfe373e7940280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:23:06 -0300 Subject: [PATCH 131/335] CONTRIBUTING: note to discourage additional contributions that pertain to old HTTP semantic conventions (#2765) --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 302e2e7481..990d6b14a2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -250,7 +250,9 @@ The continuous integration overrides that environment variable with as per the c Below is a checklist of things to be mindful of when implementing a new instrumentation or working on a specific instrumentation. It is one of our goals as a community to keep the implementation specific details of instrumentations as similar across the board as possible for ease of testing and feature parity. It is also good to abstract as much common functionality as possible. - Follow semantic conventions - - The instrumentation should follow the semantic conventions defined [here](https://github.com/open-telemetry/semantic-conventions/tree/main/docs) + - The instrumentation should follow the semantic conventions defined [here](https://github.com/open-telemetry/semantic-conventions/tree/main/docs). + - To ensure consistency, we encourage contributions that align with [STABLE](https://opentelemetry.io/docs/specs/otel/document-status/#lifecycle-status) semantic conventions if available. This approach helps us avoid potential confusion and reduces the need to support multiple outdated versions of semantic conventions. However, we are still open to considering exceptional cases where changes are well justified. + - Contributions related to outdated HTTP semantic conventions (conventions prior to becoming [stable](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0)) will likely be discouraged, as they increase complexity and the potential for misconceptions. - Contains a name that is not already claimed in [Pypi](https://pypi.org/). Contact a maintainer, bring the issue up in the weekly Python SIG or create a ticket in Pypi if a desired name has already been taken. - Extends from [BaseInstrumentor](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/2518a4ac07cb62ad6587dd8f6cbb5f8663a7e179/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py#L35) - Supports auto-instrumentation From 4ea9e5a99a6e4ade3dc76a87b4b893ecfafb9f8e Mon Sep 17 00:00:00 2001 From: Daniel Torok Date: Thu, 1 Aug 2024 22:24:18 +0100 Subject: [PATCH 132/335] Fixing w3c baggage support in opentelemetry-instrumentation-aws-lambda (#2589) * Fixing w3c baggage support in opentelemetry-instrumentation-aws-lambda * Changelog update * Passing context not needed * Fixing unit test after rebase --- CHANGELOG.md | 9 ++ .../instrumentation/aws_lambda/__init__.py | 122 ++++++++++-------- .../tests/mocks/lambda_function.py | 7 +- .../test_aws_lambda_instrumentation_manual.py | 37 +++++- 4 files changed, 115 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a47bb6fe0a..237a73786c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Added + +## Breaking changes + ## Fixed - `opentelemetry-instrumentation-aws-lambda` Avoid exception when a handler is not present. @@ -17,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2483](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2484)) - `opentelemetry-instrumentation-fastapi` Fix fastapi-slim support ([#2756](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2756)) +- `opentelemetry-instrumentation-aws-lambda` Fixing w3c baggage support + ([#2589](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2589)) ## Version 1.26.0/0.47b0 (2024-07-23) @@ -113,7 +119,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) - `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. ([#2627](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2627)) +<<<<<<< HEAD - `opentelemetry-instrumentation-mysql` Add support for `mysql-connector-python` v9 ([#2751](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2751)) +======= +>>>>>>> 5a623233 (Changelog update) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index 883296d85b..fb5da8ce48 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -76,6 +76,7 @@ def custom_event_context_extractor(lambda_event): from wrapt import wrap_function_wrapper +from opentelemetry import context as context_api from opentelemetry.context.context import Context from opentelemetry.instrumentation.aws_lambda.package import _instruments from opentelemetry.instrumentation.aws_lambda.version import __version__ @@ -303,66 +304,75 @@ def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches schema_url="https://opentelemetry.io/schemas/1.11.0", ) - with tracer.start_as_current_span( - name=orig_handler_name, - context=parent_context, - kind=span_kind, - ) as span: - if span.is_recording(): - lambda_context = args[1] - # NOTE: The specs mention an exception here, allowing the - # `SpanAttributes.CLOUD_RESOURCE_ID` attribute to be set as a span - # attribute instead of a resource attribute. - # - # See more: - # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#resource-detector - span.set_attribute( - SpanAttributes.CLOUD_RESOURCE_ID, - lambda_context.invoked_function_arn, - ) - span.set_attribute( - SpanAttributes.FAAS_INVOCATION_ID, - lambda_context.aws_request_id, - ) - - # NOTE: `cloud.account.id` can be parsed from the ARN as the fifth item when splitting on `:` - # - # See more: - # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#all-triggers - account_id = lambda_context.invoked_function_arn.split(":")[4] - span.set_attribute( - ResourceAttributes.CLOUD_ACCOUNT_ID, - account_id, - ) + token = context_api.attach(parent_context) + try: + with tracer.start_as_current_span( + name=orig_handler_name, + kind=span_kind, + ) as span: + if span.is_recording(): + lambda_context = args[1] + # NOTE: The specs mention an exception here, allowing the + # `SpanAttributes.CLOUD_RESOURCE_ID` attribute to be set as a span + # attribute instead of a resource attribute. + # + # See more: + # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#resource-detector + span.set_attribute( + SpanAttributes.CLOUD_RESOURCE_ID, + lambda_context.invoked_function_arn, + ) + span.set_attribute( + SpanAttributes.FAAS_INVOCATION_ID, + lambda_context.aws_request_id, + ) - exception = None - result = None - try: - result = call_wrapped(*args, **kwargs) - except Exception as exc: # pylint: disable=W0703 - exception = exc - span.set_status(Status(StatusCode.ERROR)) - span.record_exception(exception) - - # If the request came from an API Gateway, extract http attributes from the event - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#api-gateway - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-server-semantic-conventions - if isinstance(lambda_event, dict) and lambda_event.get( - "requestContext" - ): - span.set_attribute(SpanAttributes.FAAS_TRIGGER, "http") - - if lambda_event.get("version") == "2.0": - _set_api_gateway_v2_proxy_attributes(lambda_event, span) - else: - _set_api_gateway_v1_proxy_attributes(lambda_event, span) - - if isinstance(result, dict) and result.get("statusCode"): + # NOTE: `cloud.account.id` can be parsed from the ARN as the fifth item when splitting on `:` + # + # See more: + # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#all-triggers + account_id = lambda_context.invoked_function_arn.split( + ":" + )[4] span.set_attribute( - SpanAttributes.HTTP_STATUS_CODE, - result.get("statusCode"), + ResourceAttributes.CLOUD_ACCOUNT_ID, + account_id, ) + exception = None + result = None + try: + result = call_wrapped(*args, **kwargs) + except Exception as exc: # pylint: disable=W0703 + exception = exc + span.set_status(Status(StatusCode.ERROR)) + span.record_exception(exception) + + # If the request came from an API Gateway, extract http attributes from the event + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#api-gateway + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-server-semantic-conventions + if isinstance(lambda_event, dict) and lambda_event.get( + "requestContext" + ): + span.set_attribute(SpanAttributes.FAAS_TRIGGER, "http") + + if lambda_event.get("version") == "2.0": + _set_api_gateway_v2_proxy_attributes( + lambda_event, span + ) + else: + _set_api_gateway_v1_proxy_attributes( + lambda_event, span + ) + + if isinstance(result, dict) and result.get("statusCode"): + span.set_attribute( + SpanAttributes.HTTP_STATUS_CODE, + result.get("statusCode"), + ) + finally: + context_api.detach(token) + now = time.time() _tracer_provider = tracer_provider or get_tracer_provider() if hasattr(_tracer_provider, "force_flush"): diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py index 539c896a0b..0387152951 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/lambda_function.py @@ -12,9 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json + +from opentelemetry import baggage as baggage_api + def handler(event, context): - return "200 ok" + baggage_content = dict(baggage_api.get_all().items()) + return json.dumps({"baggage_content": baggage_content}) def rest_api_handler(event, context): diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index 00940547ea..3a71e83aa2 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import json import os from dataclasses import dataclass from importlib import import_module, reload @@ -19,6 +19,7 @@ from unittest import mock from opentelemetry import propagate +from opentelemetry.baggage.propagation import W3CBaggagePropagator from opentelemetry.environment_variables import OTEL_PROPAGATORS from opentelemetry.instrumentation.aws_lambda import ( _HANDLER, @@ -79,6 +80,9 @@ def __init__(self, aws_request_id, invoked_function_arn): MOCK_W3C_TRACE_STATE_KEY = "vendor_specific_key" MOCK_W3C_TRACE_STATE_VALUE = "test_value" +MOCK_W3C_BAGGAGE_KEY = "baggage_key" +MOCK_W3C_BAGGAGE_VALUE = "baggage_value" + def mock_execute_lambda(event=None): """Mocks the AWS Lambda execution. @@ -97,7 +101,7 @@ def mock_execute_lambda(event=None): module_name, handler_name = os.environ[_HANDLER].rsplit(".", 1) handler_module = import_module(module_name.replace("/", ".")) - getattr(handler_module, handler_name)(event, MOCK_LAMBDA_CONTEXT) + return getattr(handler_module, handler_name)(event, MOCK_LAMBDA_CONTEXT) class TestAwsLambdaInstrumentor(TestBase): @@ -181,6 +185,9 @@ class TestCase: expected_state_value: str = None expected_trace_state_len: int = 0 propagators: str = "tracecontext" + expected_baggage: str = None + disable_aws_context_propagation: bool = False + disable_aws_context_propagation_envvar: str = "" def custom_event_context_extractor(lambda_event): return get_global_textmap().extract(lambda_event["foo"]["headers"]) @@ -266,6 +273,24 @@ def custom_event_context_extractor(lambda_event): expected_state_value=MOCK_W3C_TRACE_STATE_VALUE, xray_traceid=MOCK_XRAY_TRACE_CONTEXT_SAMPLED, ), + TestCase( + name="baggage_propagation", + custom_extractor=None, + context={ + "headers": { + TraceContextTextMapPropagator._TRACEPARENT_HEADER_NAME: MOCK_W3C_TRACE_CONTEXT_SAMPLED, + TraceContextTextMapPropagator._TRACESTATE_HEADER_NAME: f"{MOCK_W3C_TRACE_STATE_KEY}={MOCK_W3C_TRACE_STATE_VALUE},foo=1,bar=2", + W3CBaggagePropagator._BAGGAGE_HEADER_NAME: f"{MOCK_W3C_BAGGAGE_KEY}={MOCK_W3C_BAGGAGE_VALUE}", + } + }, + expected_traceid=MOCK_W3C_TRACE_ID, + expected_parentid=MOCK_W3C_PARENT_SPAN_ID, + expected_trace_state_len=3, + expected_state_value=MOCK_W3C_TRACE_STATE_VALUE, + xray_traceid=MOCK_XRAY_TRACE_CONTEXT_NOT_SAMPLED, + expected_baggage=MOCK_W3C_BAGGAGE_VALUE, + propagators="tracecontext,baggage", + ), ] for test in tests: @@ -284,7 +309,9 @@ def custom_event_context_extractor(lambda_event): AwsLambdaInstrumentor().instrument( event_context_extractor=test.custom_extractor, ) - mock_execute_lambda(test.context) + result = mock_execute_lambda(test.context) + result = json.loads(result) + spans = self.memory_exporter.get_finished_spans() assert spans self.assertEqual(len(spans), 1) @@ -305,6 +332,10 @@ def custom_event_context_extractor(lambda_event): parent_context.trace_state.get(MOCK_W3C_TRACE_STATE_KEY), test.expected_state_value, ) + self.assertEqual( + result["baggage_content"].get(MOCK_W3C_BAGGAGE_KEY), + test.expected_baggage, + ) self.assertTrue(parent_context.is_remote) self.memory_exporter.clear() AwsLambdaInstrumentor().uninstrument() From c3e9f75fb9611d1e2842b4f3fe11b910d7d2ae0c Mon Sep 17 00:00:00 2001 From: Malcolm Rebughini <9681621+malcolmrebughini@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:33:29 -0700 Subject: [PATCH 133/335] =?UTF-8?q?fix(opentelemetry-instrumentation-celer?= =?UTF-8?q?y):=20attach=20incoming=20context=20on=E2=80=A6=20(#2385)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(opentelemetry-instrumentation-celery): attach incoming context on _trace_prerun * docs(CHANGELOG): add entry for fix #2385 * fix(opentelemetry-instrumentation-celery): detach context after task is run * test(opentelemetry-instrumentation-celery): add context utils tests * fix(opentelemetry-instrumentation-celery): remove duplicated signal registration * refactor(opentelemetry-instrumentation-celery): fix lint issues * refactor(opentelemetry-instrumentation-celery): fix types and tests for python 3.8 * refactor(opentelemetry-instrumentation-celery): fix lint issues * refactor(opentelemetry-instrumentation-celery): fix lint issues * fix(opentelemetry-instrumentation-celery): attach context only if it is not None * refactor(opentelemetry-instrumentation-celery): fix lint issues --- CHANGELOG.md | 8 +-- .../instrumentation/celery/__init__.py | 48 +++++++++++---- .../instrumentation/celery/utils.py | 59 ++++++++++++------- .../tests/celery_test_tasks.py | 7 +++ .../tests/test_tasks.py | 19 +++++- .../tests/test_utils.py | 22 +++---- 6 files changed, 114 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 237a73786c..0984efa3de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2756](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2756)) - `opentelemetry-instrumentation-aws-lambda` Fixing w3c baggage support ([#2589](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2589)) +- `opentelemetry-instrumentation-celery` propagates baggage + ([#2385](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2385)) ## Version 1.26.0/0.47b0 (2024-07-23) @@ -119,10 +121,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2610)) - `opentelemetry-instrumentation-asgi` Bugfix: Middleware did not set status code attribute on duration metrics for non-recording spans. ([#2627](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2627)) -<<<<<<< HEAD -- `opentelemetry-instrumentation-mysql` Add support for `mysql-connector-python` v9 ([#2751](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2751)) -======= ->>>>>>> 5a623233 (Changelog update) +- `opentelemetry-instrumentation-mysql` Add support for `mysql-connector-python` v9 + ([#2751](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2751)) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py index 10ccca1270..39b3bffe60 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py @@ -67,6 +67,7 @@ def add(x, y): from billiard.einfo import ExceptionInfo from celery import signals # pylint: disable=no-name-in-module +from opentelemetry import context as context_api from opentelemetry import trace from opentelemetry.instrumentation.celery import utils from opentelemetry.instrumentation.celery.package import _instruments @@ -169,6 +170,7 @@ def _trace_prerun(self, *args, **kwargs): self.update_task_duration_time(task_id) request = task.request tracectx = extract(request, getter=celery_getter) or None + token = context_api.attach(tracectx) if tracectx is not None else None logger.debug("prerun signal start task_id=%s", task_id) @@ -179,7 +181,7 @@ def _trace_prerun(self, *args, **kwargs): activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 - utils.attach_span(task, task_id, (span, activation)) + utils.attach_context(task, task_id, span, activation, token) def _trace_postrun(self, *args, **kwargs): task = utils.retrieve_task(kwargs) @@ -191,11 +193,14 @@ def _trace_postrun(self, *args, **kwargs): logger.debug("postrun signal task_id=%s", task_id) # retrieve and finish the Span - span, activation = utils.retrieve_span(task, task_id) - if span is None: + ctx = utils.retrieve_context(task, task_id) + + if ctx is None: logger.warning("no existing span found for task_id=%s", task_id) return + span, activation, token = ctx + # request context tags if span.is_recording(): span.set_attribute(_TASK_TAG_KEY, _TASK_RUN) @@ -204,10 +209,11 @@ def _trace_postrun(self, *args, **kwargs): span.set_attribute(_TASK_NAME_KEY, task.name) activation.__exit__(None, None, None) - utils.detach_span(task, task_id) + utils.detach_context(task, task_id) self.update_task_duration_time(task_id) labels = {"task": task.name, "worker": task.request.hostname} self._record_histograms(task_id, labels) + context_api.detach(token) def _trace_before_publish(self, *args, **kwargs): task = utils.retrieve_task_from_sender(kwargs) @@ -238,7 +244,9 @@ def _trace_before_publish(self, *args, **kwargs): activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 - utils.attach_span(task, task_id, (span, activation), is_publish=True) + utils.attach_context( + task, task_id, span, activation, None, is_publish=True + ) headers = kwargs.get("headers") if headers: @@ -253,13 +261,16 @@ def _trace_after_publish(*args, **kwargs): return # retrieve and finish the Span - _, activation = utils.retrieve_span(task, task_id, is_publish=True) - if activation is None: + ctx = utils.retrieve_context(task, task_id, is_publish=True) + + if ctx is None: logger.warning("no existing span found for task_id=%s", task_id) return + _, activation, _ = ctx + activation.__exit__(None, None, None) # pylint: disable=E1101 - utils.detach_span(task, task_id, is_publish=True) + utils.detach_context(task, task_id, is_publish=True) @staticmethod def _trace_failure(*args, **kwargs): @@ -269,9 +280,14 @@ def _trace_failure(*args, **kwargs): if task is None or task_id is None: return - # retrieve and pass exception info to activation - span, _ = utils.retrieve_span(task, task_id) - if span is None or not span.is_recording(): + ctx = utils.retrieve_context(task, task_id) + + if ctx is None: + return + + span, _, _ = ctx + + if not span.is_recording(): return status_kwargs = {"status_code": StatusCode.ERROR} @@ -311,8 +327,14 @@ def _trace_retry(*args, **kwargs): if task is None or task_id is None or reason is None: return - span, _ = utils.retrieve_span(task, task_id) - if span is None or not span.is_recording(): + ctx = utils.retrieve_context(task, task_id) + + if ctx is None: + return + + span, _, _ = ctx + + if not span.is_recording(): return # Add retry reason metadata to span diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py index 6f4f9cbc3a..6af310df5a 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py @@ -13,10 +13,13 @@ # limitations under the License. import logging +from typing import ContextManager, Optional, Tuple from celery import registry # pylint: disable=no-name-in-module +from celery.app.task import Task from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.trace import Span logger = logging.getLogger(__name__) @@ -81,10 +84,12 @@ def set_attributes_from_context(span, context): elif key == "delivery_info": # Get also destination from this routing_key = value.get("routing_key") + if routing_key is not None: span.set_attribute( SpanAttributes.MESSAGING_DESTINATION, routing_key ) + value = str(value) elif key == "id": @@ -114,11 +119,18 @@ def set_attributes_from_context(span, context): span.set_attribute(attribute_name, value) -def attach_span(task, task_id, span, is_publish=False): - """Helper to propagate a `Span` for the given `Task` instance. This - function uses a `dict` that stores the Span using the - `(task_id, is_publish)` as a key. This is useful when information must be - propagated from one Celery signal to another. +def attach_context( + task: Optional[Task], + task_id: str, + span: Span, + activation: ContextManager[Span], + token: Optional[object], + is_publish: bool = False, +) -> None: + """Helper to propagate a `Span`, `ContextManager` and context token + for the given `Task` instance. This function uses a `dict` that stores + the Span using the `(task_id, is_publish)` as a key. This is useful + when information must be propagated from one Celery signal to another. We use (task_id, is_publish) for the key to ensure that publishing a task from within another task does not cause any conflicts. @@ -134,36 +146,41 @@ def attach_span(task, task_id, span, is_publish=False): """ if task is None: return - span_dict = getattr(task, CTX_KEY, None) - if span_dict is None: - span_dict = {} - setattr(task, CTX_KEY, span_dict) - span_dict[(task_id, is_publish)] = span + ctx_dict = getattr(task, CTX_KEY, None) + + if ctx_dict is None: + ctx_dict = {} + setattr(task, CTX_KEY, ctx_dict) + + ctx_dict[(task_id, is_publish)] = (span, activation, token) -def detach_span(task, task_id, is_publish=False): - """Helper to remove a `Span` in a Celery task when it's propagated. - This function handles tasks where the `Span` is not attached. +def detach_context(task, task_id, is_publish=False) -> None: + """Helper to remove `Span`, `ContextManager` and context token in a + Celery task when it's propagated. + This function handles tasks where no values are attached to the `Task`. """ span_dict = getattr(task, CTX_KEY, None) if span_dict is None: return - # See note in `attach_span` for key info - span_dict.pop((task_id, is_publish), (None, None)) + # See note in `attach_context` for key info + span_dict.pop((task_id, is_publish), None) -def retrieve_span(task, task_id, is_publish=False): - """Helper to retrieve an active `Span` stored in a `Task` - instance +def retrieve_context( + task, task_id, is_publish=False +) -> Optional[Tuple[Span, ContextManager[Span], Optional[object]]]: + """Helper to retrieve an active `Span`, `ContextManager` and context token + stored in a `Task` instance """ span_dict = getattr(task, CTX_KEY, None) if span_dict is None: - return (None, None) + return None - # See note in `attach_span` for key info - return span_dict.get((task_id, is_publish), (None, None)) + # See note in `attach_context` for key info + return span_dict.get((task_id, is_publish), None) def retrieve_task(kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py index 9ac78f6d8b..af88f1d4c3 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py @@ -14,6 +14,8 @@ from celery import Celery +from opentelemetry import baggage + class Config: result_backend = "rpc" @@ -36,3 +38,8 @@ def task_add(num_a, num_b): @app.task def task_raises(): raise CustomError("The task failed!") + + +@app.task +def task_returns_baggage(): + return dict(baggage.get_all()) diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py index 3ac6a5a70c..0dc668b112 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py @@ -15,12 +15,13 @@ import threading import time +from opentelemetry import baggage, context from opentelemetry.instrumentation.celery import CeleryInstrumentor from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind, StatusCode -from .celery_test_tasks import app, task_add, task_raises +from .celery_test_tasks import app, task_add, task_raises, task_returns_baggage class TestCeleryInstrumentation(TestBase): @@ -168,6 +169,22 @@ def test_uninstrument(self): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) + def test_baggage(self): + CeleryInstrumentor().instrument() + + ctx = baggage.set_baggage("key", "value") + context.attach(ctx) + + task = task_returns_baggage.delay() + + timeout = time.time() + 60 * 1 # 1 minutes from now + while not task.ready(): + if time.time() > timeout: + break + time.sleep(0.05) + + self.assertEqual(task.result, {"key": "value"}) + class TestCelerySignatureTask(TestBase): def setUp(self): diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/test_utils.py b/instrumentation/opentelemetry-instrumentation-celery/tests/test_utils.py index 55aa3eec1e..a2f6e4338c 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/tests/test_utils.py +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/test_utils.py @@ -167,8 +167,10 @@ def fn_task(): # propagate and retrieve a Span task_id = "7c6731af-9533-40c3-83a9-25b58f0d837f" span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) - utils.attach_span(fn_task, task_id, span) - span_after = utils.retrieve_span(fn_task, task_id) + utils.attach_context(fn_task, task_id, span, mock.Mock(), "") + ctx = utils.retrieve_context(fn_task, task_id) + self.assertIsNotNone(ctx) + span_after, _, _ = ctx self.assertIs(span, span_after) def test_span_delete(self): @@ -180,17 +182,19 @@ def fn_task(): # propagate a Span task_id = "7c6731af-9533-40c3-83a9-25b58f0d837f" span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) - utils.attach_span(fn_task, task_id, span) + utils.attach_context(fn_task, task_id, span, mock.Mock(), "") # delete the Span - utils.detach_span(fn_task, task_id) - self.assertEqual(utils.retrieve_span(fn_task, task_id), (None, None)) + utils.detach_context(fn_task, task_id) + self.assertEqual(utils.retrieve_context(fn_task, task_id), None) def test_optional_task_span_attach(self): task_id = "7c6731af-9533-40c3-83a9-25b58f0d837f" span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) # assert this is is a no-aop - self.assertIsNone(utils.attach_span(None, task_id, span)) + self.assertIsNone( + utils.attach_context(None, task_id, span, mock.Mock(), "") + ) def test_span_delete_empty(self): # ensure detach_span doesn't raise an exception if span is not present @@ -201,10 +205,8 @@ def fn_task(): # delete the Span task_id = "7c6731af-9533-40c3-83a9-25b58f0d837f" try: - utils.detach_span(fn_task, task_id) - self.assertEqual( - utils.retrieve_span(fn_task, task_id), (None, None) - ) + utils.detach_context(fn_task, task_id) + self.assertEqual(utils.retrieve_context(fn_task, task_id), None) except Exception as ex: # pylint: disable=broad-except self.fail(f"Exception was raised: {ex}") From 3e185602281c8594ff53f9d667e3813b93ba79c4 Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Thu, 1 Aug 2024 23:15:34 +0100 Subject: [PATCH 134/335] feat: add header extraction parameters to `FastAPIInstrumentor().instrument_app` (#2241) * add header parameters to FastAPIInstrumentor().instrument_app * add changelog * move #2072 changelog to unreleased * remove accidental pprint * linting * future annotations for fastapi * same logic for instrument() * Fix lint * Fix test case --------- Co-authored-by: Diego Hurtado --- CHANGELOG.md | 8 +- .../instrumentation/fastapi/__init__.py | 39 +- .../tests/test_fastapi_instrumentation.py | 534 +++++++++++++++++- 3 files changed, 571 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0984efa3de..f3d9b5e40a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -216,6 +216,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2367](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2367)) +### Added +- `opentelemetry-instrumentation-fastapi` Add support for configuring header extraction via runtime constructor parameters + ([#2241](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2241)) + ## Version 1.23.0/0.44b0 (2024-02-23) - Drop support for 3.7 @@ -236,6 +240,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `opentelemetry-instrumentation-psycopg` Initial release for psycopg 3.x +- `opentelemetry-instrumentation-asgi` Add support for configuring ASGI middleware header extraction via runtime constructor parameters + ([#2026](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2026)) ## Version 1.22.0/0.43b0 (2023-12-14) @@ -275,8 +281,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1948](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1948)) - Added schema_url (`"https://opentelemetry.io/schemas/1.11.0"`) to all metrics and traces ([#1977](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1977)) -- Add support for configuring ASGI middleware header extraction via runtime constructor parameters - ([#2026](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2026)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index bfb4f4a682..fdb035baa8 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -86,9 +86,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A Request headers *************** To capture HTTP request headers as span attributes, set the environment variable -``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST`` to a comma delimited list of HTTP header names. +``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST`` to a comma delimited list of HTTP header names, +or pass the ``http_capture_headers_server_request`` keyword argument to the ``instrument_app`` method. -For example, +For example using the environment variable, :: export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST="content-type,custom_request_header" @@ -120,9 +121,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A Response headers **************** To capture HTTP response headers as span attributes, set the environment variable -``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE`` to a comma delimited list of HTTP header names. +``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE`` to a comma delimited list of HTTP header names, +or pass the ``http_capture_headers_server_response`` keyword argument to the ``instrument_app`` method. -For example, +For example using the environment variable, :: export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE="content-type,custom_response_header" @@ -155,10 +157,12 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A ****************** In order to prevent storing sensitive data such as personally identifiable information (PII), session keys, passwords, etc, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS`` -to a comma delimited list of HTTP header names to be sanitized. Regexes may be used, and all header names will be -matched in a case-insensitive manner. +to a comma delimited list of HTTP header names to be sanitized, or pass the ``http_capture_headers_sanitize_fields`` +keyword argument to the ``instrument_app`` method. -For example, +Regexes may be used, and all header names will be matched in a case-insensitive manner. + +For example using the environment variable, :: export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS=".*session.*,set-cookie" @@ -171,6 +175,9 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A API --- """ + +from __future__ import annotations + import logging from importlib.metadata import PackageNotFoundError, distribution from typing import Collection @@ -227,6 +234,9 @@ def instrument_app( tracer_provider=None, meter_provider=None, excluded_urls=None, + http_capture_headers_server_request: list[str] | None = None, + http_capture_headers_server_response: list[str] | None = None, + http_capture_headers_sanitize_fields: list[str] | None = None, ): """Instrument an uninstrumented FastAPI application.""" if not hasattr(app, "_is_instrumented_by_opentelemetry"): @@ -265,6 +275,9 @@ def instrument_app( # Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation tracer=tracer, meter=meter, + http_capture_headers_server_request=http_capture_headers_server_request, + http_capture_headers_server_response=http_capture_headers_server_response, + http_capture_headers_sanitize_fields=http_capture_headers_sanitize_fields, ) app._is_instrumented_by_opentelemetry = True if app not in _InstrumentedFastAPI._instrumented_fastapi_apps: @@ -314,6 +327,15 @@ def _instrument(self, **kwargs): _InstrumentedFastAPI._client_response_hook = kwargs.get( "client_response_hook" ) + _InstrumentedFastAPI._http_capture_headers_server_request = kwargs.get( + "http_capture_headers_server_request" + ) + _InstrumentedFastAPI._http_capture_headers_server_response = ( + kwargs.get("http_capture_headers_server_response") + ) + _InstrumentedFastAPI._http_capture_headers_sanitize_fields = ( + kwargs.get("http_capture_headers_sanitize_fields") + ) _excluded_urls = kwargs.get("excluded_urls") _InstrumentedFastAPI._excluded_urls = ( _excluded_urls_from_env @@ -368,6 +390,9 @@ def __init__(self, *args, **kwargs): # Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation tracer=tracer, meter=meter, + http_capture_headers_server_request=_InstrumentedFastAPI._http_capture_headers_server_request, + http_capture_headers_server_response=_InstrumentedFastAPI._http_capture_headers_server_response, + http_capture_headers_sanitize_fields=_InstrumentedFastAPI._http_capture_headers_sanitize_fields, ) self._is_instrumented_by_opentelemetry = True _InstrumentedFastAPI._instrumented_fastapi_apps.add(self) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index d233331283..03fdd6749d 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -20,9 +20,11 @@ import fastapi from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware +from fastapi.responses import JSONResponse from fastapi.testclient import TestClient import opentelemetry.instrumentation.fastapi as otel_fastapi +from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, @@ -47,8 +49,14 @@ ) from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.test.globals_test import reset_trace_globals from opentelemetry.test.test_base import TestBase -from opentelemetry.util.http import get_excluded_urls +from opentelemetry.util.http import ( + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, + get_excluded_urls, +) _expected_metric_names_old = [ "http.server.active_requests", @@ -1227,3 +1235,527 @@ def test_instrumentation(self): should_be_original = fastapi.FastAPI self.assertIs(original, should_be_original) + + +class TestWrappedApplication(TestBase): + def setUp(self): + super().setUp() + + self.app = fastapi.FastAPI() + + @self.app.get("/foobar") + async def _(): + return {"message": "hello world"} + + otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) + self.client = TestClient(self.app) + self.tracer = self.tracer_provider.get_tracer(__name__) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) + + def test_mark_span_internal_in_presence_of_span_from_other_framework(self): + with self.tracer.start_as_current_span( + "test", kind=trace.SpanKind.SERVER + ) as parent_span: + resp = self.client.get("/foobar") + self.assertEqual(200, resp.status_code) + + span_list = self.memory_exporter.get_finished_spans() + for span in span_list: + print(str(span.__class__) + ": " + str(span.__dict__)) + + # there should be 4 spans - single SERVER "test" and three INTERNAL "FastAPI" + self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind) + self.assertEqual(trace.SpanKind.INTERNAL, span_list[1].kind) + # main INTERNAL span - child of test + self.assertEqual(trace.SpanKind.INTERNAL, span_list[2].kind) + self.assertEqual( + parent_span.context.span_id, span_list[2].parent.span_id + ) + # SERVER "test" + self.assertEqual(trace.SpanKind.SERVER, span_list[3].kind) + self.assertEqual( + parent_span.context.span_id, span_list[3].context.span_id + ) + + +@patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*", + }, +) +class TestHTTPAppWithCustomHeaders(TestBase): + def setUp(self): + super().setUp() + self.app = self._create_app() + otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) + self.client = TestClient(self.app) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) + + @staticmethod + def _create_app(): + app = fastapi.FastAPI() + + @app.get("/foobar") + async def _(): + headers = { + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + "my-custom-regex-header-1": "my-custom-regex-value-1,my-custom-regex-value-2", + "My-Custom-Regex-Header-2": "my-custom-regex-value-3,my-custom-regex-value-4", + "My-Secret-Header": "My Secret Value", + } + content = {"message": "hello world"} + return JSONResponse(content=content, headers=headers) + + return app + + def test_http_custom_request_headers_in_span_attributes(self): + expected = { + "http.request.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.request.header.custom_test_header_2": ( + "test-header-value-2", + ), + "http.request.header.regex_test_header_1": ("Regex Test Value 1",), + "http.request.header.regex_test_header_2": ( + "RegexTestValue2,RegexTestValue3", + ), + "http.request.header.my_secret_header": ("[REDACTED]",), + } + resp = self.client.get( + "/foobar", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + "Regex-Test-Header-1": "Regex Test Value 1", + "regex-test-header-2": "RegexTestValue2,RegexTestValue3", + "My-Secret-Header": "My Secret Value", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + self.assertSpanHasAttributes(server_span, expected) + + def test_http_custom_request_headers_not_in_span_attributes(self): + not_expected = { + "http.request.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + resp = self.client.get( + "/foobar", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + "Regex-Test-Header-1": "Regex Test Value 1", + "regex-test-header-2": "RegexTestValue2,RegexTestValue3", + "My-Secret-Header": "My Secret Value", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + def test_http_custom_response_headers_in_span_attributes(self): + expected = { + "http.response.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.response.header.custom_test_header_2": ( + "test-header-value-2", + ), + "http.response.header.my_custom_regex_header_1": ( + "my-custom-regex-value-1,my-custom-regex-value-2", + ), + "http.response.header.my_custom_regex_header_2": ( + "my-custom-regex-value-3,my-custom-regex-value-4", + ), + "http.response.header.my_secret_header": ("[REDACTED]",), + } + resp = self.client.get("/foobar") + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + self.assertSpanHasAttributes(server_span, expected) + + def test_http_custom_response_headers_not_in_span_attributes(self): + not_expected = { + "http.response.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + resp = self.client.get("/foobar") + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + +class TestHTTPAppWithCustomHeadersParameters(TestBase): + """Minimal tests here since the behavior of this logic is tested above and in the ASGI tests.""" + + def setUp(self): + super().setUp() + self.instrumentor = otel_fastapi.FastAPIInstrumentor() + self.kwargs = { + "http_capture_headers_server_request": ["a.*", "b.*"], + "http_capture_headers_server_response": ["c.*", "d.*"], + "http_capture_headers_sanitize_fields": [".*secret.*"], + } + self.app = None + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + if self.app: + self.instrumentor.uninstrument_app(self.app) + else: + self.instrumentor.uninstrument() + + @staticmethod + def _create_app(): + app = fastapi.FastAPI() + + @app.get("/foobar") + async def _(): + headers = { + "carrot": "bar", + "date-secret": "yellow", + "egg": "ham", + } + content = {"message": "hello world"} + return JSONResponse(content=content, headers=headers) + + return app + + def test_http_custom_request_headers_in_span_attributes_app(self): + self.app = self._create_app() + self.instrumentor.instrument_app(self.app, **self.kwargs) + + resp = TestClient(self.app).get( + "/foobar", + headers={ + "apple": "red", + "banana-secret": "yellow", + "fig": "green", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + expected = { + # apple should be included because it starts with a + "http.request.header.apple": ("red",), + # same with banana because it starts with b, + # redacted because it contains "secret" + "http.request.header.banana_secret": ("[REDACTED]",), + } + self.assertSpanHasAttributes(server_span, expected) + self.assertNotIn("http.request.header.fig", server_span.attributes) + + def test_http_custom_request_headers_in_span_attributes_instr(self): + """As above, but use instrument(), not instrument_app().""" + self.instrumentor.instrument(**self.kwargs) + + resp = TestClient(self._create_app()).get( + "/foobar", + headers={ + "apple": "red", + "banana-secret": "yellow", + "fig": "green", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + expected = { + # apple should be included because it starts with a + "http.request.header.apple": ("red",), + # same with banana because it starts with b, + # redacted because it contains "secret" + "http.request.header.banana_secret": ("[REDACTED]",), + } + self.assertSpanHasAttributes(server_span, expected) + self.assertNotIn("http.request.header.fig", server_span.attributes) + + def test_http_custom_response_headers_in_span_attributes_app(self): + self.app = self._create_app() + self.instrumentor.instrument_app(self.app, **self.kwargs) + resp = TestClient(self.app).get("/foobar") + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + expected = { + "http.response.header.carrot": ("bar",), + "http.response.header.date_secret": ("[REDACTED]",), + } + self.assertSpanHasAttributes(server_span, expected) + self.assertNotIn("http.response.header.egg", server_span.attributes) + + def test_http_custom_response_headers_in_span_attributes_inst(self): + """As above, but use instrument(), not instrument_app().""" + self.instrumentor.instrument(**self.kwargs) + + resp = TestClient(self._create_app()).get("/foobar") + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 3) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + expected = { + "http.response.header.carrot": ("bar",), + "http.response.header.date_secret": ("[REDACTED]",), + } + self.assertSpanHasAttributes(server_span, expected) + self.assertNotIn("http.response.header.egg", server_span.attributes) + + +@patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*", + }, +) +class TestWebSocketAppWithCustomHeaders(TestBase): + def setUp(self): + super().setUp() + self.app = self._create_app() + otel_fastapi.FastAPIInstrumentor().instrument_app(self.app) + self.client = TestClient(self.app) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app) + + @staticmethod + def _create_app(): + app = fastapi.FastAPI() + + @app.websocket("/foobar_web") + async def _(websocket: fastapi.WebSocket): + message = await websocket.receive() + if message.get("type") == "websocket.connect": + await websocket.send( + { + "type": "websocket.accept", + "headers": [ + (b"custom-test-header-1", b"test-header-value-1"), + (b"custom-test-header-2", b"test-header-value-2"), + (b"Regex-Test-Header-1", b"Regex Test Value 1"), + ( + b"regex-test-header-2", + b"RegexTestValue2,RegexTestValue3", + ), + (b"My-Secret-Header", b"My Secret Value"), + ], + } + ) + await websocket.send_json({"message": "hello world"}) + await websocket.close() + if message.get("type") == "websocket.disconnect": + pass + + return app + + def test_web_socket_custom_request_headers_in_span_attributes(self): + expected = { + "http.request.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.request.header.custom_test_header_2": ( + "test-header-value-2", + ), + } + + with self.client.websocket_connect( + "/foobar_web", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + }, + ) as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + self.assertSpanHasAttributes(server_span, expected) + + @patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*", + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*", + }, + ) + def test_web_socket_custom_request_headers_not_in_span_attributes(self): + not_expected = { + "http.request.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + + with self.client.websocket_connect( + "/foobar_web", + headers={ + "custom-test-header-1": "test-header-value-1", + "custom-test-header-2": "test-header-value-2", + }, + ) as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + def test_web_socket_custom_response_headers_in_span_attributes(self): + expected = { + "http.response.header.custom_test_header_1": ( + "test-header-value-1", + ), + "http.response.header.custom_test_header_2": ( + "test-header-value-2", + ), + } + + with self.client.websocket_connect("/foobar_web") as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + self.assertSpanHasAttributes(server_span, expected) + + def test_web_socket_custom_response_headers_not_in_span_attributes(self): + not_expected = { + "http.response.header.custom_test_header_3": ( + "test-header-value-3", + ), + } + + with self.client.websocket_connect("/foobar_web") as websocket: + data = websocket.receive_json() + self.assertEqual(data, {"message": "hello world"}) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 5) + + server_span = [ + span for span in span_list if span.kind == trace.SpanKind.SERVER + ][0] + + for key, _ in not_expected.items(): + self.assertNotIn(key, server_span.attributes) + + +@patch.dict( + "os.environ", + { + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3", + }, +) +class TestNonRecordingSpanWithCustomHeaders(TestBase): + def setUp(self): + super().setUp() + self.app = fastapi.FastAPI() + + @self.app.get("/foobar") + async def _(): + return {"message": "hello world"} + + reset_trace_globals() + tracer_provider = trace.NoOpTracerProvider() + trace.set_tracer_provider(tracer_provider=tracer_provider) + + self._instrumentor = otel_fastapi.FastAPIInstrumentor() + self._instrumentor.instrument_app(self.app) + self.client = TestClient(self.app) + + def tearDown(self) -> None: + super().tearDown() + with self.disable_logging(): + self._instrumentor.uninstrument_app(self.app) + + def test_custom_header_not_present_in_non_recording_span(self): + resp = self.client.get( + "/foobar", + headers={ + "custom-test-header-1": "test-header-value-1", + }, + ) + self.assertEqual(200, resp.status_code) + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 0) From 265490fc78539b91ab7ae306ce924f10a4e14d9b Mon Sep 17 00:00:00 2001 From: RJ Duffner Date: Fri, 2 Aug 2024 11:59:17 -0700 Subject: [PATCH 135/335] kafka-python Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation (#2537) * Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation * Make kafkapython-ng run tests --- .github/workflows/instrumentations_1.yml | 1 + CHANGELOG.md | 4 ++++ instrumentation/README.md | 2 +- .../pyproject.toml | 4 +++- .../instrumentation/kafka/__init__.py | 24 ++++++++++++++++++- .../instrumentation/kafka/package.py | 5 +++- .../test-requirements-ng.txt | 15 ++++++++++++ .../instrumentation/bootstrap_gen.py | 6 ++++- tox.ini | 9 +++++++ 9 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 2658f4d4b2..1421d7f9a5 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -40,6 +40,7 @@ jobs: - "util-http" - "fastapislim" - "processor-baggage" + - "kafka-pythonng" os: [ubuntu-20.04] exclude: - python-version: pypy3 diff --git a/CHANGELOG.md b/CHANGELOG.md index f3d9b5e40a..e3b91462ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Added +- `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng + inside kafka-python's instrumentation + ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537))) + ## Breaking changes ## Fixed diff --git a/instrumentation/README.md b/instrumentation/README.md index 278182e61f..c45f6ba325 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -24,7 +24,7 @@ | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental | [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration | [opentelemetry-instrumentation-jinja2](./opentelemetry-instrumentation-jinja2) | jinja2 >= 2.7, < 4.0 | No | experimental -| [opentelemetry-instrumentation-kafka-python](./opentelemetry-instrumentation-kafka-python) | kafka-python >= 2.0 | No | experimental +| [opentelemetry-instrumentation-kafka-python](./opentelemetry-instrumentation-kafka-python) | kafka-python >= 2.0, < 3.0,kafka-python-ng >= 2.0, < 3.0 | No | experimental | [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging | No | experimental | [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python >= 8.0, < 10.0 | No | experimental | [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index f9c0cf8332..c256c71b94 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dependencies = [ "opentelemetry-api ~= 1.5", @@ -31,7 +32,8 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "kafka-python >= 2.0", + "kafka-python >= 2.0, < 3.0", + "kafka-python-ng >= 2.0, < 3.0" ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py index 8d7378dfdf..b29990d6e3 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py @@ -67,6 +67,7 @@ def consume_hook(span, record, args, kwargs): API ___ """ +from importlib.metadata import PackageNotFoundError, distribution from typing import Collection import kafka @@ -74,7 +75,11 @@ def consume_hook(span, record, args, kwargs): from opentelemetry import trace from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.kafka.package import _instruments +from opentelemetry.instrumentation.kafka.package import ( + _instruments, + _instruments_kafka_python, + _instruments_kafka_python_ng, +) from opentelemetry.instrumentation.kafka.utils import _wrap_next, _wrap_send from opentelemetry.instrumentation.kafka.version import __version__ from opentelemetry.instrumentation.utils import unwrap @@ -86,6 +91,23 @@ class KafkaInstrumentor(BaseInstrumentor): """ def instrumentation_dependencies(self) -> Collection[str]: + # Determine which package of kafka-python is installed + # Right now there are two packages, kafka-python and kafka-python-ng + # The latter is a fork of the former because the former is connected + # to a pypi namespace that the current maintainers cannot access + # https://github.com/dpkp/kafka-python/issues/2431 + try: + distribution("kafka-python-ng") + return (_instruments_kafka_python_ng,) + except PackageNotFoundError: + pass + + try: + distribution("kafka-python") + return (_instruments_kafka_python,) + except PackageNotFoundError: + pass + return _instruments def _instrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/package.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/package.py index 04863fb7b4..3a4a5e5de6 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/package.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/package.py @@ -13,4 +13,7 @@ # limitations under the License. -_instruments = ("kafka-python >= 2.0",) +_instruments_kafka_python = "kafka-python >= 2.0, < 3.0" +_instruments_kafka_python_ng = "kafka-python-ng >= 2.0, < 3.0" + +_instruments = (_instruments_kafka_python, _instruments_kafka_python_ng) diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt new file mode 100644 index 0000000000..7b587031ec --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt @@ -0,0 +1,15 @@ +asgiref==3.7.2 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +kafka-python-ng==2.2.2 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +tomli==2.0.1 +typing_extensions==4.9.0 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-kafka-python diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 0deb99b8bf..1868f6a3a1 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -105,7 +105,11 @@ "instrumentation": "opentelemetry-instrumentation-jinja2==0.48b0.dev", }, { - "library": "kafka-python >= 2.0", + "library": "kafka-python >= 2.0, < 3.0", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.48b0.dev", + }, + { + "library": "kafka-python-ng >= 2.0, < 3.0", "instrumentation": "opentelemetry-instrumentation-kafka-python==0.48b0.dev", }, { diff --git a/tox.ini b/tox.ini index 27eaaa9129..2396b4495a 100644 --- a/tox.ini +++ b/tox.ini @@ -350,7 +350,9 @@ envlist = ; opentelemetry-instrumentation-kafka-python py3{8,9,10,11}-test-instrumentation-kafka-python + py3{8,9,10,11,12}-test-instrumentation-kafka-pythonng pypy3-test-instrumentation-kafka-python + pypy3-test-instrumentation-kafka-pythonng lint-instrumentation-kafka-python ; opentelemetry-instrumentation-confluent-kafka @@ -443,6 +445,10 @@ commands_pre = kafka-python: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions kafka-python: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk kafka-python: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt + kafka-pythonng: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + kafka-pythonng: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + kafka-pythonng: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + kafka-pythonng: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt confluent-kafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api confluent-kafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -940,6 +946,9 @@ commands = lint-instrumentation-kafka-python: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python lint-instrumentation-kafka-python: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-kafka-python" + ; Test only for kafka-pythonng instrumentation as the only difference between kafka-python and kafka-pythonng is the version of kafka-python + test-instrumentation-kafka-pythonng: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/tests {posargs} + test-instrumentation-confluent-kafka: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests {posargs} lint-instrumentation-confluent-kafka: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka From ca0dd50c43245a4ca2ae63fd50e2f907b18ff245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:31:06 -0300 Subject: [PATCH 136/335] bump zipp (#2770) --- .../opentelemetry-instrumentation-grpc/test-requirements-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index 6d9531cd5e..94412a8f60 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -15,6 +15,6 @@ pytest-benchmark==4.0.0 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 -zipp==3.17.0 +zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-grpc From 0d28c8b978234c48f578b12c5a761d792b9dab87 Mon Sep 17 00:00:00 2001 From: Joshua Fenton Date: Tue, 6 Aug 2024 02:10:37 +1000 Subject: [PATCH 137/335] Increase test coverage of instrumentation-aws-lambda (#2760) --- .../mocks/alb_conventional_headers_event.py | 24 ++ .../mocks/alb_multi_value_headers_event.py | 30 ++ .../tests/mocks/dynamo_db_event.py | 48 +++ .../tests/mocks/s3_event.py | 36 ++ .../tests/mocks/sns_event.py | 29 ++ .../tests/mocks/sqs_event.py | 24 ++ .../test_aws_lambda_instrumentation_manual.py | 398 ++++++++++++------ 7 files changed, 458 insertions(+), 131 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_conventional_headers_event.py create mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_multi_value_headers_event.py create mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/dynamo_db_event.py create mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/s3_event.py create mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sns_event.py create mode 100644 instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sqs_event.py diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_conventional_headers_event.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_conventional_headers_event.py new file mode 100644 index 0000000000..7462f2a64e --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_conventional_headers_event.py @@ -0,0 +1,24 @@ +MOCK_LAMBDA_ALB_EVENT = { + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" + } + }, + "httpMethod": "GET", + "path": "/", + "queryStringParameters": {"foo": "bar"}, + "headers": { + "accept": "text/html,application/xhtml+xml", + "accept-language": "en-US,en;q=0.8", + "content-type": "text/plain", + "cookie": "cookies", + "host": "lambda-846800462-us-east-2.elb.amazonaws.com", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)", + "x-amzn-trace-id": "Root=1-5bdb40ca-556d8b0c50dc66f0511bf520", + "x-forwarded-for": "72.21.198.66", + "x-forwarded-port": "443", + "x-forwarded-proto": "https", + }, + "isBase64Encoded": False, + "body": "request_body", +} diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_multi_value_headers_event.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_multi_value_headers_event.py new file mode 100644 index 0000000000..bf7c2ae686 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/alb_multi_value_headers_event.py @@ -0,0 +1,30 @@ +""" +https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers + +When an ALB is configured to send multi-value headers, the headers are sent as a list of values under the key in the multiValueHeaders object. +""" + +MOCK_LAMBDA_ALB_MULTI_VALUE_HEADER_EVENT = { + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" + } + }, + "httpMethod": "GET", + "path": "/", + "queryStringParameters": {"foo": "bar"}, + "multiValueHeaders": { + "accept": ["text/html,application/xhtml+xml"], + "accept-language": ["en-US,en;q=0.8"], + "content-type": ["text/plain"], + "cookie": ["cookies"], + "host": ["lambda-846800462-us-east-2.elb.amazonaws.com"], + "user-agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)"], + "x-amzn-trace-id": ["Root=1-5bdb40ca-556d8b0c50dc66f0511bf520"], + "x-forwarded-for": ["72.21.198.66"], + "x-forwarded-port": ["443"], + "x-forwarded-proto": ["https"], + }, + "isBase64Encoded": False, + "body": "request_body", +} diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/dynamo_db_event.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/dynamo_db_event.py new file mode 100644 index 0000000000..ea11237082 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/dynamo_db_event.py @@ -0,0 +1,48 @@ +""" +https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html +""" + +MOCK_LAMBDA_DYNAMO_DB_EVENT = { + "Records": [ + { + "eventID": "1", + "eventVersion": "1.0", + "dynamodb": { + "Keys": {"Id": {"N": "101"}}, + "NewImage": { + "Message": {"S": "New item!"}, + "Id": {"N": "101"}, + }, + "StreamViewType": "NEW_AND_OLD_IMAGES", + "SequenceNumber": "111", + "SizeBytes": 26, + }, + "awsRegion": "us-west-2", + "eventName": "INSERT", + "eventSourceARN": "arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2023-06-10T19:26:16.525", + "eventSource": "aws:dynamodb", + }, + { + "eventID": "2", + "eventVersion": "1.0", + "dynamodb": { + "OldImage": { + "Message": {"S": "New item!"}, + "Id": {"N": "101"}, + }, + "SequenceNumber": "222", + "Keys": {"Id": {"N": "101"}}, + "SizeBytes": 59, + "NewImage": { + "Message": {"S": "This item has changed"}, + "Id": {"N": "101"}, + }, + "StreamViewType": "NEW_AND_OLD_IMAGES", + }, + "awsRegion": "us-west-2", + "eventName": "MODIFY", + "eventSourceARN": "arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2023-06-10T19:26:16.525", + "eventSource": "aws:dynamodb", + }, + ] +} diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/s3_event.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/s3_event.py new file mode 100644 index 0000000000..8a866c0d4d --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/s3_event.py @@ -0,0 +1,36 @@ +""" +https://docs.aws.amazon.com/lambda/latest/dg/with-s3.html +""" + +MOCK_LAMBDA_S3_EVENT = { + "Records": [ + { + "eventVersion": "2.1", + "eventSource": "aws:s3", + "awsRegion": "us-east-2", + "eventTime": "2019-09-03T19:37:27.192Z", + "eventName": "ObjectCreated:Put", + "userIdentity": {"principalId": "AWS:AIDAINPONIXQXHT3IKHL2"}, + "requestParameters": {"sourceIPAddress": "205.255.255.255"}, + "responseElements": { + "x-amz-request-id": "D82B88E5F771F645", + "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=", + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1", + "bucket": { + "name": "DOC-EXAMPLE-BUCKET", + "ownerIdentity": {"principalId": "A3I5XTEXAMAI3E"}, + "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df", + }, + "object": { + "key": "b21b84d653bb07b05b1e6b33684dc11b", + "size": 1305107, + "eTag": "b21b84d653bb07b05b1e6b33684dc11b", + "sequencer": "0C0F6F405D6ED209E1", + }, + }, + } + ] +} diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sns_event.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sns_event.py new file mode 100644 index 0000000000..f53155e26f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sns_event.py @@ -0,0 +1,29 @@ +""" +https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html +""" + +MOCK_LAMBDA_SNS_EVENT = { + "Records": [ + { + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", + "EventSource": "aws:sns", + "Sns": { + "SignatureVersion": "1", + "Timestamp": "2019-01-02T12:45:07.000Z", + "Signature": "mock-signature", + "SigningCertURL": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", + "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", + "Message": "Hello from SNS!", + "MessageAttributes": { + "Test": {"Type": "String", "Value": "TestString"}, + "TestBinary": {"Type": "Binary", "Value": "TestBinary"}, + }, + "Type": "Notification", + "UnsubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", + "TopicArn": "arn:aws:sns:us-east-1:123456789012:sns-lambda", + "Subject": "TestInvoke", + }, + } + ] +} diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sqs_event.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sqs_event.py new file mode 100644 index 0000000000..081ff9debd --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/mocks/sqs_event.py @@ -0,0 +1,24 @@ +""" +https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html +""" + +MOCK_LAMBDA_SQS_EVENT = { + "Records": [ + { + "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", + "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "body": "Test message.", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1545082649183", + "SenderId": "AIDAIENQZJOLO23YVJ4VO", + "ApproximateFirstReceiveTimestamp": "1545082649185", + }, + "messageAttributes": {}, + "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", + "awsRegion": "us-east-2", + } + ] +} diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index 3a71e83aa2..7f805c327c 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import json import os from dataclasses import dataclass from importlib import import_module, reload @@ -41,10 +40,18 @@ ) from opentelemetry.util._importlib_metadata import entry_points +from .mocks.alb_conventional_headers_event import MOCK_LAMBDA_ALB_EVENT +from .mocks.alb_multi_value_headers_event import ( + MOCK_LAMBDA_ALB_MULTI_VALUE_HEADER_EVENT, +) from .mocks.api_gateway_http_api_event import ( MOCK_LAMBDA_API_GATEWAY_HTTP_API_EVENT, ) from .mocks.api_gateway_proxy_event import MOCK_LAMBDA_API_GATEWAY_PROXY_EVENT +from .mocks.dynamo_db_event import MOCK_LAMBDA_DYNAMO_DB_EVENT +from .mocks.s3_event import MOCK_LAMBDA_S3_EVENT +from .mocks.sns_event import MOCK_LAMBDA_SNS_EVENT +from .mocks.sqs_event import MOCK_LAMBDA_SQS_EVENT class MockLambdaContext: @@ -58,8 +65,17 @@ def __init__(self, aws_request_id, invoked_function_arn): invoked_function_arn="arn:aws:lambda:us-east-1:123456:function:myfunction:myalias", ) -MOCK_XRAY_TRACE_ID = 0x5FB7331105E8BB83207FA31D4D9CDB4C +MOCK_LAMBDA_CONTEXT_ATTRIBUTES = { + SpanAttributes.CLOUD_RESOURCE_ID: MOCK_LAMBDA_CONTEXT.invoked_function_arn, + SpanAttributes.FAAS_INVOCATION_ID: MOCK_LAMBDA_CONTEXT.aws_request_id, + ResourceAttributes.CLOUD_ACCOUNT_ID: MOCK_LAMBDA_CONTEXT.invoked_function_arn.split( + ":" + )[ + 4 + ], +} +MOCK_XRAY_TRACE_ID = 0x5FB7331105E8BB83207FA31D4D9CDB4C MOCK_XRAY_TRACE_ID_STR = f"{MOCK_XRAY_TRACE_ID:x}" MOCK_XRAY_PARENT_SPAN_ID = 0x3328B8445A6DBAD2 MOCK_XRAY_TRACE_CONTEXT_COMMON = f"Root={TRACE_ID_VERSION}-{MOCK_XRAY_TRACE_ID_STR[:TRACE_ID_FIRST_PART_LENGTH]}-{MOCK_XRAY_TRACE_ID_STR[TRACE_ID_FIRST_PART_LENGTH:]};Parent={MOCK_XRAY_PARENT_SPAN_ID:x}" @@ -88,7 +104,6 @@ def mock_execute_lambda(event=None): """Mocks the AWS Lambda execution. NOTE: We don't use `moto`'s `mock_lambda` because we are not instrumenting - calls to AWS Lambda using the AWS SDK. Instead, we are instrumenting AWS Lambda itself. @@ -104,7 +119,7 @@ def mock_execute_lambda(event=None): return getattr(handler_module, handler_name)(event, MOCK_LAMBDA_CONTEXT) -class TestAwsLambdaInstrumentor(TestBase): +class TestAwsLambdaInstrumentorBase(TestBase): """AWS Lambda Instrumentation Testsuite""" def setUp(self): @@ -124,6 +139,8 @@ def tearDown(self): self.common_env_patch.stop() AwsLambdaInstrumentor().uninstrument() + +class TestAwsLambdaInstrumentor(TestAwsLambdaInstrumentorBase): def test_active_tracing(self): test_env_patch = mock.patch.dict( "os.environ", @@ -153,15 +170,7 @@ def test_active_tracing(self): self.assertEqual(span.kind, SpanKind.SERVER) self.assertSpanHasAttributes( span, - { - SpanAttributes.CLOUD_RESOURCE_ID: MOCK_LAMBDA_CONTEXT.invoked_function_arn, - SpanAttributes.FAAS_INVOCATION_ID: MOCK_LAMBDA_CONTEXT.aws_request_id, - ResourceAttributes.CLOUD_ACCOUNT_ID: MOCK_LAMBDA_CONTEXT.invoked_function_arn.split( - ":" - )[ - 4 - ], - }, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, ) parent_context = span.parent @@ -293,53 +302,52 @@ def custom_event_context_extractor(lambda_event): ), ] for test in tests: + with self.subTest(test_name=test.name): + test_env_patch = mock.patch.dict( + "os.environ", + { + **os.environ, + # NOT Active Tracing + _X_AMZN_TRACE_ID: test.xray_traceid, + OTEL_PROPAGATORS: test.propagators, + }, + ) + test_env_patch.start() + reload(propagate) - test_env_patch = mock.patch.dict( - "os.environ", - { - **os.environ, - # NOT Active Tracing - _X_AMZN_TRACE_ID: test.xray_traceid, - OTEL_PROPAGATORS: test.propagators, - }, - ) - test_env_patch.start() - reload(propagate) + AwsLambdaInstrumentor().instrument( + event_context_extractor=test.custom_extractor, + ) - AwsLambdaInstrumentor().instrument( - event_context_extractor=test.custom_extractor, - ) - result = mock_execute_lambda(test.context) - result = json.loads(result) - - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 1) - span = spans[0] - self.assertEqual( - span.get_span_context().trace_id, test.expected_traceid - ) + mock_execute_lambda(test.context) - parent_context = span.parent - self.assertEqual( - parent_context.trace_id, span.get_span_context().trace_id - ) - self.assertEqual(parent_context.span_id, test.expected_parentid) - self.assertEqual( - len(parent_context.trace_state), test.expected_trace_state_len - ) - self.assertEqual( - parent_context.trace_state.get(MOCK_W3C_TRACE_STATE_KEY), - test.expected_state_value, - ) - self.assertEqual( - result["baggage_content"].get(MOCK_W3C_BAGGAGE_KEY), - test.expected_baggage, - ) - self.assertTrue(parent_context.is_remote) - self.memory_exporter.clear() - AwsLambdaInstrumentor().uninstrument() - test_env_patch.stop() + spans = self.memory_exporter.get_finished_spans() + assert spans + self.assertEqual(len(spans), 1) + span = spans[0] + self.assertEqual( + span.get_span_context().trace_id, test.expected_traceid + ) + + parent_context = span.parent + self.assertEqual( + parent_context.trace_id, span.get_span_context().trace_id + ) + self.assertEqual( + parent_context.span_id, test.expected_parentid + ) + self.assertEqual( + len(parent_context.trace_state), + test.expected_trace_state_len, + ) + self.assertEqual( + parent_context.trace_state.get(MOCK_W3C_TRACE_STATE_KEY), + test.expected_state_value, + ) + self.assertTrue(parent_context.is_remote) + self.memory_exporter.clear() + AwsLambdaInstrumentor().uninstrument() + test_env_patch.stop() def test_lambda_no_error_with_invalid_flush_timeout(self): test_env_patch = mock.patch.dict( @@ -419,57 +427,16 @@ def test_lambda_handles_invalid_event_source(self): assert spans assert len(spans) == 1 - assert ( - spans[0].kind == SpanKind.SERVER - ) # Default to SERVER for unknown sources - - test_env_patch.stop() - - def test_api_gateway_proxy_event_sets_attributes(self): - handler_patch = mock.patch.dict( - "os.environ", - {_HANDLER: "tests.mocks.lambda_function.rest_api_handler"}, - ) - handler_patch.start() + # Default to SERVER for unknown sources + assert spans[0].kind == SpanKind.SERVER - AwsLambdaInstrumentor().instrument() - - mock_execute_lambda(MOCK_LAMBDA_API_GATEWAY_PROXY_EVENT) - - span = self.memory_exporter.get_finished_spans()[0] - - self.assertSpanHasAttributes( - span, - { - SpanAttributes.FAAS_TRIGGER: "http", - SpanAttributes.HTTP_METHOD: "POST", - SpanAttributes.HTTP_ROUTE: "/{proxy+}", - SpanAttributes.HTTP_TARGET: "/{proxy+}?foo=bar", - SpanAttributes.NET_HOST_NAME: "1234567890.execute-api.us-east-1.amazonaws.com", - SpanAttributes.HTTP_USER_AGENT: "Custom User Agent String", - SpanAttributes.HTTP_SCHEME: "https", - SpanAttributes.HTTP_STATUS_CODE: 200, - }, - ) - - def test_api_gateway_http_api_proxy_event_sets_attributes(self): - AwsLambdaInstrumentor().instrument() - - mock_execute_lambda(MOCK_LAMBDA_API_GATEWAY_HTTP_API_EVENT) - - span = self.memory_exporter.get_finished_spans()[0] + for span in spans: + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) - self.assertSpanHasAttributes( - span, - { - SpanAttributes.FAAS_TRIGGER: "http", - SpanAttributes.HTTP_METHOD: "POST", - SpanAttributes.HTTP_ROUTE: "/path/to/resource", - SpanAttributes.HTTP_TARGET: "/path/to/resource?parameter1=value1¶meter1=value2¶meter2=value", - SpanAttributes.NET_HOST_NAME: "id.execute-api.us-east-1.amazonaws.com", - SpanAttributes.HTTP_USER_AGENT: "agent", - }, - ) + test_env_patch.stop() def test_lambda_handles_list_event(self): AwsLambdaInstrumentor().instrument() @@ -501,31 +468,6 @@ def test_lambda_handles_handler_exception(self): exc_env_patch.stop() - def test_lambda_handles_handler_exception_with_api_gateway_proxy_event( - self, - ): - exc_env_patch = mock.patch.dict( - "os.environ", - {_HANDLER: "tests.mocks.lambda_function.handler_exc"}, - ) - exc_env_patch.start() - AwsLambdaInstrumentor().instrument() - # instrumentor re-raises the exception - with self.assertRaises(Exception): - mock_execute_lambda( - {"requestContext": {"http": {"method": "GET"}}} - ) - - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 1) - span = spans[0] - self.assertEqual(span.status.status_code, StatusCode.ERROR) - self.assertEqual(len(span.events), 1) - event = span.events[0] - self.assertEqual(event.name, "exception") - - exc_env_patch.stop() - def test_lambda_handles_should_do_nothing_when_environment_variables_not_present( self, ): @@ -575,3 +517,197 @@ def test_load_entry_point(self): ).load(), AwsLambdaInstrumentor, ) + + +class TestAwsLambdaInstrumentorMocks(TestAwsLambdaInstrumentorBase): + def test_api_gateway_proxy_event_sets_attributes(self): + handler_patch = mock.patch.dict( + "os.environ", + {_HANDLER: "tests.mocks.lambda_function.rest_api_handler"}, + ) + handler_patch.start() + + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_API_GATEWAY_PROXY_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.FAAS_TRIGGER: "http", + SpanAttributes.HTTP_METHOD: "POST", + SpanAttributes.HTTP_ROUTE: "/{proxy+}", + SpanAttributes.HTTP_TARGET: "/{proxy+}?foo=bar", + SpanAttributes.NET_HOST_NAME: "1234567890.execute-api.us-east-1.amazonaws.com", + SpanAttributes.HTTP_USER_AGENT: "Custom User Agent String", + SpanAttributes.HTTP_SCHEME: "https", + SpanAttributes.HTTP_STATUS_CODE: 200, + }, + ) + + def test_api_gateway_http_api_proxy_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_API_GATEWAY_HTTP_API_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.FAAS_TRIGGER: "http", + SpanAttributes.HTTP_METHOD: "POST", + SpanAttributes.HTTP_ROUTE: "/path/to/resource", + SpanAttributes.HTTP_TARGET: "/path/to/resource?parameter1=value1¶meter1=value2¶meter2=value", + SpanAttributes.NET_HOST_NAME: "id.execute-api.us-east-1.amazonaws.com", + SpanAttributes.HTTP_USER_AGENT: "agent", + }, + ) + + def test_alb_conventional_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_ALB_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.FAAS_TRIGGER: "http", + SpanAttributes.HTTP_METHOD: "GET", + }, + ) + + def test_alb_multi_value_header_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_ALB_MULTI_VALUE_HEADER_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.SERVER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.FAAS_TRIGGER: "http", + SpanAttributes.HTTP_METHOD: "GET", + }, + ) + + def test_dynamo_db_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_DYNAMO_DB_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.CONSUMER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + + def test_s3_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_S3_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.CONSUMER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + + def test_sns_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_SNS_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.CONSUMER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + + def test_sqs_event_sets_attributes(self): + AwsLambdaInstrumentor().instrument() + + mock_execute_lambda(MOCK_LAMBDA_SQS_EVENT) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.kind, SpanKind.CONSUMER) + self.assertSpanHasAttributes( + span, + MOCK_LAMBDA_CONTEXT_ATTRIBUTES, + ) + + def test_lambda_handles_handler_exception_with_api_gateway_proxy_event( + self, + ): + exc_env_patch = mock.patch.dict( + "os.environ", + {_HANDLER: "tests.mocks.lambda_function.handler_exc"}, + ) + exc_env_patch.start() + AwsLambdaInstrumentor().instrument() + + # instrumentor re-raises the exception + with self.assertRaises(Exception): + mock_execute_lambda( + {"requestContext": {"http": {"method": "GET"}}} + ) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span, *_ = spans + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual(len(span.events), 1) + + event, *_ = span.events + self.assertEqual(event.name, "exception") + + exc_env_patch.stop() From aeac52301a74cba309dd2f08d3f510fa4d492fa1 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 5 Aug 2024 18:45:13 +0200 Subject: [PATCH 138/335] tox: run tests for real for fastapislim (#2771) --- .github/workflows/instrumentations_1.yml | 1 - tox.ini | 15 +++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml index 1421d7f9a5..c020b972eb 100644 --- a/.github/workflows/instrumentations_1.yml +++ b/.github/workflows/instrumentations_1.yml @@ -38,7 +38,6 @@ jobs: - "resource-detector-azure" - "resource-detector-container" - "util-http" - - "fastapislim" - "processor-baggage" - "kafka-pythonng" os: [ubuntu-20.04] diff --git a/tox.ini b/tox.ini index 2396b4495a..faa50aa711 100644 --- a/tox.ini +++ b/tox.ini @@ -115,10 +115,8 @@ envlist = lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi - py3{8,9,10,11,12}-test-instrumentation-fastapi - py3{8,9,10,11,12}-test-instrumentation-fastapislim - pypy3-test-instrumentation-fastapi - pypy3-test-instrumentation-fastapislim + py3{8,9,10,11,12}-test-instrumentation-fastapi-{main,slim} + pypy3-test-instrumentation-fastapi-{main,slim} lint-instrumentation-fastapi ; opentelemetry-instrumentation-flask @@ -561,12 +559,9 @@ commands_pre = fastapi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions fastapi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk fastapi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt - fastapislim: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - fastapislim: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - fastapislim: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - fastapislim: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - fastapislim: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt + fastapi-main: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt + fastapi-slim: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt + lint-instrumentation-fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt mysql: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api mysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions From 76919d3089761f57644c0655bd66b58e4cd96d1b Mon Sep 17 00:00:00 2001 From: Ben Beasley Date: Mon, 5 Aug 2024 13:04:48 -0400 Subject: [PATCH 139/335] Loosen fastapi-slim version bound to be like the one for fastapi (#2775) --- instrumentation/README.md | 2 +- .../opentelemetry-instrumentation-fastapi/pyproject.toml | 2 +- .../src/opentelemetry/instrumentation/fastapi/package.py | 2 +- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/README.md b/instrumentation/README.md index c45f6ba325..378497db79 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -19,7 +19,7 @@ | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental | [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 4.0.0 | Yes | experimental -| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58,fastapi-slim ~= 0.111.0 | Yes | migration +| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58,fastapi-slim ~= 0.111 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental | [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 4236fde227..eec5b0f10f 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -35,7 +35,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ "fastapi ~= 0.58", - "fastapi-slim ~= 0.111.0", + "fastapi-slim ~= 0.111", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py index 55e1059d7a..55cf4b3646 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py @@ -14,7 +14,7 @@ _fastapi = "fastapi ~= 0.58" -_fastapi_slim = "fastapi-slim ~= 0.111.0" +_fastapi_slim = "fastapi-slim ~= 0.111" _instruments = (_fastapi, _fastapi_slim) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 1868f6a3a1..1c9bd63874 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -85,7 +85,7 @@ "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", }, { - "library": "fastapi-slim ~= 0.111.0", + "library": "fastapi-slim ~= 0.111", "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", }, { From 8bfae49a7a7548f5db59c71d7f95213a716c7fc5 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 5 Aug 2024 19:18:56 +0200 Subject: [PATCH 140/335] requirements: sync grpcio test requirements (#2777) --- .../test-requirements-1.txt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index 94412a8f60..221359e184 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -1,17 +1,13 @@ asgiref==3.7.2 -attrs==23.2.0 Deprecated==1.2.14 grpcio==1.63.0 importlib-metadata==6.11.0 iniconfig==2.0.0 -packaging==23.2 -pluggy==1.4.0 +packaging==24.0 +pluggy==1.5.0 protobuf==3.20.3 -py==1.11.0 py-cpuinfo==9.0.0 -pytest==7.1.3 -pytest-asyncio==0.23.5 -pytest-benchmark==4.0.0 +pytest==7.4.4 tomli==2.0.1 typing_extensions==4.9.0 wrapt==1.16.0 From 2a707bccceb32ec8254caa8156ea903bfaf06d68 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 5 Aug 2024 10:43:04 -0700 Subject: [PATCH 141/335] Bump version for aws propagator and aws sdk extension for release (#2773) --- .../opentelemetry-instrumentation-aws-lambda/pyproject.toml | 2 +- .../opentelemetry-instrumentation-botocore/pyproject.toml | 2 +- .../src/opentelemetry/propagators/aws/version.py | 2 +- .../src/opentelemetry/sdk/extension/aws/version.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index 4d6b431d91..b512faa3eb 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-propagator-aws-xray == 1.0.1", + "opentelemetry-propagator-aws-xray ~= 1.0.1", "opentelemetry-semantic-conventions == 0.48b0.dev", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 4714a7261f..f286e7fc7b 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.48b0.dev", "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-propagator-aws-xray == 1.0.1", + "opentelemetry-propagator-aws-xray ~= 1.0.1", ] [project.optional-dependencies] diff --git a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py index 58cce81ce6..1a30b96547 100644 --- a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py +++ b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "1.0.1" +__version__ = "1.0.2" diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py index a889da2799..c9cb3877e2 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.0.1" +__version__ = "2.0.2" From f0d8cb39e90ff7029e10f4b8d96b136c5497be02 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 6 Aug 2024 16:27:38 -0600 Subject: [PATCH 142/335] Generate workflow files with a Jinja template (#2687) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Generate workflow files with a Jinja template Fixes #2686 * Remove sudo from allowlist_externals * Update workflows * Add condition to skip generate-workflows * Update workflows * Update .github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Update .github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Update .github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Update .github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Update workflows * Update workflows --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/generate_workflows.py | 14 + .../generate_workflows_lib/hatch_build.py | 15 + .../generate_workflows_lib/pyproject.toml | 32 + .../src/generate_workflows_lib/.gitignore | 1 + .../src/generate_workflows_lib/__init__.py | 267 + .../src/generate_workflows_lib/contrib.yml.j2 | 47 + .../src/generate_workflows_lib/lint.yml.j2 | 37 + .../src/generate_workflows_lib/misc.yml.j2 | 67 + .../src/generate_workflows_lib/test.yml.j2 | 42 + .../src/generate_workflows_lib/version.py | 1 + .github/workflows/instrumentations_0.yml | 119 - .github/workflows/lint.yml | 95 - .github/workflows/lint_0.yml | 1061 ++++ .github/workflows/misc_0.yml | 129 + .github/workflows/shellcheck.yml | 19 - .github/workflows/test.yml | 40 - .github/workflows/test_0.yml | 4517 +++++++++++++++++ .github/workflows/test_1.yml | 3797 ++++++++++++++ tox.ini | 35 +- 19 files changed, 10051 insertions(+), 284 deletions(-) create mode 100644 .github/workflows/generate_workflows.py create mode 100644 .github/workflows/generate_workflows_lib/hatch_build.py create mode 100644 .github/workflows/generate_workflows_lib/pyproject.toml create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/.gitignore create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/version.py delete mode 100644 .github/workflows/instrumentations_0.yml delete mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/lint_0.yml create mode 100644 .github/workflows/misc_0.yml delete mode 100644 .github/workflows/shellcheck.yml delete mode 100644 .github/workflows/test.yml create mode 100644 .github/workflows/test_0.yml create mode 100644 .github/workflows/test_1.yml diff --git a/.github/workflows/generate_workflows.py b/.github/workflows/generate_workflows.py new file mode 100644 index 0000000000..dbd128bc43 --- /dev/null +++ b/.github/workflows/generate_workflows.py @@ -0,0 +1,14 @@ +from pathlib import Path + +from generate_workflows_lib import ( + generate_test_workflow, + generate_lint_workflow, + generate_misc_workflow +) + +tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") +workflows_directory_path = Path(__file__).parent + +generate_test_workflow(tox_ini_path, workflows_directory_path, "ubuntu-latest") +generate_lint_workflow(tox_ini_path, workflows_directory_path) +generate_misc_workflow(tox_ini_path, workflows_directory_path) diff --git a/.github/workflows/generate_workflows_lib/hatch_build.py b/.github/workflows/generate_workflows_lib/hatch_build.py new file mode 100644 index 0000000000..aedf360a35 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/hatch_build.py @@ -0,0 +1,15 @@ +from hatchling.builders.hooks.plugin.interface import BuildHookInterface +from pathlib import Path + + +class CustomBuildHook(BuildHookInterface): + + def initialize(self, version, build_data): + + with open( + Path(__file__).parent.parent.parent.parent.joinpath("tox.ini") + ) as tox_ini_file_0: + with open( + Path(__file__).parent.joinpath("src/generate_workflows_lib/tox.ini"), "w" + ) as tox_ini_file_1: + tox_ini_file_1.write(tox_ini_file_0.read()) diff --git a/.github/workflows/generate_workflows_lib/pyproject.toml b/.github/workflows/generate_workflows_lib/pyproject.toml new file mode 100644 index 0000000000..314d079686 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/pyproject.toml @@ -0,0 +1,32 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "generate-workflows-lib" +dynamic = ["version"] +description = "A library to generate workflows" +license = "Apache-2.0" +requires-python = ">=3.8" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Typing :: Typed", +] +dependencies = ["Jinja2", "tox"] + +[tool.hatch.version] +path = "src/generate_workflows_lib/version.py" + +[tool.hatch.build.targets.wheel.hooks.custom] diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/.gitignore b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/.gitignore new file mode 100644 index 0000000000..66d10d9ec4 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/.gitignore @@ -0,0 +1 @@ +tox.ini diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py new file mode 100644 index 0000000000..31f11062c4 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -0,0 +1,267 @@ +from re import compile as re_compile +from jinja2 import Environment, FileSystemLoader +from pathlib import Path +from tox.config.cli.parse import get_options +from tox.session.state import State +from tox.config.sets import CoreConfigSet +from tox.config.source.tox_ini import ToxIni +from collections import defaultdict + + +_tox_test_env_regex = re_compile( + r"(?Ppy\w+)-test-" + r"(?P[-\w]+\w)-?(?P\d+)?" +) +_tox_lint_env_regex = re_compile(r"lint-(?P[-\w]+)") +_tox_contrib_env_regex = re_compile( + r"py38-test-(?P[-\w]+\w)-?(?P\d+)?" +) + + +def get_tox_envs(tox_ini_path: Path) -> list: + + tox_ini = ToxIni(tox_ini_path) + + conf = State(get_options(), []).conf + + tox_section = next(tox_ini.sections()) + + core_config_set = ( + CoreConfigSet(conf, tox_section, tox_ini_path.parent, tox_ini_path) + ) + + ( + core_config_set. + loaders. + extend( + tox_ini. + get_loaders( + tox_section, + base=[], + override_map=defaultdict(list, {}), + conf=core_config_set + ) + ) + ) + + return core_config_set.load("env_list") + + +def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: + + os_alias = { + "ubuntu-latest": "Ubuntu", + "windows-latest": "Windows" + } + + python_version_alias = { + "pypy3": "pypy-3.8", + "py38": "3.8", + "py39": "3.9", + "py310": "3.10", + "py311": "3.11", + "py312": "3.12", + } + + test_job_datas = [] + + for operating_system in operating_systems: + for tox_env in tox_envs: + + tox_test_env_match = _tox_test_env_regex.match(tox_env) + + if tox_test_env_match is None: + continue + + groups = tox_test_env_match.groupdict() + + aliased_python_version = ( + python_version_alias[groups["python_version"]] + ) + tox_env = tox_test_env_match.string + + test_requirements = groups["test_requirements"] + + if test_requirements is None: + test_requirements = " " + + else: + test_requirements = f"-{test_requirements} " + + test_job_datas.append( + { + "name": f"{tox_env}_{operating_system}", + "ui_name": ( + f"{groups['name']}" + f"{test_requirements}" + f"{aliased_python_version} " + f"{os_alias[operating_system]}" + ), + "python_version": aliased_python_version, + "tox_env": tox_env, + "os": operating_system + } + + ) + + return test_job_datas + + +def get_lint_job_datas(tox_envs: list) -> list: + + lint_job_datas = [] + + for tox_env in tox_envs: + + tox_lint_env_match = _tox_lint_env_regex.match(tox_env) + + if tox_lint_env_match is None: + continue + + tox_env = tox_lint_env_match.string + + lint_job_datas.append( + { + "name": f"{tox_env}", + "ui_name": f"{tox_lint_env_match.groupdict()['name']}", + "tox_env": tox_env, + } + + ) + + return lint_job_datas + + +def get_contrib_job_datas(tox_envs: list) -> list: + + contrib_job_datas = [] + + for tox_env in tox_envs: + + tox_contrib_env_match = _tox_contrib_env_regex.match(tox_env) + + if tox_contrib_env_match is None: + continue + + groups = tox_contrib_env_match.groupdict() + + tox_env = tox_contrib_env_match.string + + contrib_requirements = groups["contrib_requirements"] + + if contrib_requirements is None: + contrib_requirements = " " + + else: + contrib_requirements = f"-{contrib_requirements} " + + contrib_job_datas.append( + { + "ui_name": ( + f"{groups['name']}" + f"{contrib_requirements}" + ), + "tox_env": tox_env, + } + + ) + + return contrib_job_datas + + +def get_misc_job_datas(tox_envs: list) -> list: + + misc_job_datas = [] + + _tox_benchmark_env_regex = re_compile(r"benchmark.+") + + for tox_env in tox_envs: + if ( + _tox_test_env_regex.match(tox_env) is not None or + _tox_lint_env_regex.match(tox_env) is not None or + _tox_contrib_env_regex.match(tox_env) is not None or + _tox_benchmark_env_regex.match(tox_env) is not None + ): + continue + + misc_job_datas.append(tox_env) + + return misc_job_datas + + +def _generate_workflow( + job_datas: list, name: str, workflow_directory_path: Path +): + + # Github seems to limit the amount of jobs in a workflow file, that is why + # they are split in groups of 250 per workflow file. + for file_number, job_datas in enumerate( + [ + job_datas[index:index + 250] + for index in range(0, len(job_datas), 250) + ] + ): + + with open( + workflow_directory_path.joinpath(f"{name}_{file_number}.yml"), + "w" + ) as test_yml_file: + + test_yml_file.write( + Environment( + loader=FileSystemLoader(Path(__file__).parent) + ).get_template(f"{name}.yml.j2").render( + job_datas=job_datas, file_number=file_number + ) + ) + test_yml_file.write("\n") + + +def generate_test_workflow( + tox_ini_path: Path, + workflow_directory_path: Path, + *operating_systems +) -> None: + + _generate_workflow( + get_test_job_datas(get_tox_envs(tox_ini_path), operating_systems), + "test", + workflow_directory_path + ) + + +def generate_lint_workflow( + tox_ini_path: Path, + workflow_directory_path: Path, +) -> None: + + _generate_workflow( + get_lint_job_datas(get_tox_envs(tox_ini_path)), + "lint", + workflow_directory_path + ) + + +def generate_contrib_workflow( + workflow_directory_path: Path, +) -> None: + + _generate_workflow( + get_contrib_job_datas( + get_tox_envs(Path(__file__).parent.joinpath("tox.ini")) + ), + "contrib", + workflow_directory_path + ) + + +def generate_misc_workflow( + tox_ini_path: Path, + workflow_directory_path: Path, +) -> None: + + _generate_workflow( + get_misc_job_datas(get_tox_envs(tox_ini_path)), + "misc", + workflow_directory_path + ) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 new file mode 100644 index 0000000000..2989e55974 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 @@ -0,0 +1,47 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Contrib {{ file_number }} + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: ${% raw %}{{ github.sha }}{% endraw %} + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + {%- for job_data in job_datas %} + + {{ job_data.tox_env }}: + name: {{ job_data.ui_name }} + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${% raw %}{{ env.CONTRIB_REPO_SHA }}{% endraw %} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${% raw %}{{ env.CONTRIB_REPO_SHA }}{% endraw %} + + - name: Checkout core repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + path: opentelemetry-python-core + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e {{ job_data.tox_env }} -- -ra + {%- endfor %} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 new file mode 100644 index 0000000000..6959261bba --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 @@ -0,0 +1,37 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Lint {{ file_number }} + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + {%- for job_data in job_datas %} + + {{ job_data.name }}: + name: {{ job_data.ui_name }} + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e {{ job_data.tox_env }} + {%- endfor %} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 new file mode 100644 index 0000000000..fe479ae5b2 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -0,0 +1,67 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Misc {{ file_number }} + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + {%- for job_data in job_datas %} + + {{ job_data }}: + name: {{ job_data }} + runs-on: ubuntu-latest + {%- if job_data == "generate-workflows" %} + if: | + !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') + && github.actor != 'opentelemetrybot' + {%- endif %} + steps: + - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} + uses: actions/checkout@v4 + {%- if job_data == "public-symbols-check" %} + with: + fetch-depth: 0 + + - name: Checkout main + run: git checkout main + + - name: Pull origin + run: git pull --rebase=false origin main + + - name: Checkout pull request + run: git checkout ${% raw %}{{ github.event.pull_request.head.sha }}{% endraw %} + {%- endif %} + {%- if job_data != "shellcheck" %} + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + {%- endif %} + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e {{ job_data }} + {%- if job_data == "generate-workflows" %} + + - name: Check workflows are up to date + run: git diff --exit-code || (echo 'Generated workflows are out of date, run "tox -e generate-workflows" and commit the changes in this PR.' && exit 1) + {%- endif %} + {%- if job_data == "generate" %} + + - name: Check workflows are up to date + run: git diff --exit-code || (echo 'Generated code is out of date, run "tox -e generate" and commit the changes in this PR.' && exit 1) + {%- endif %} + {%- endfor %} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 new file mode 100644 index 0000000000..e5168470d8 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 @@ -0,0 +1,42 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Test {{ file_number }} + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + {%- for job_data in job_datas %} + + {{ job_data.name }}: + name: {{ job_data.ui_name }} + runs-on: {{ job_data.os }} + steps: + - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} + uses: actions/checkout@v4 + + - name: Set up Python {{ job_data.python_version }} + uses: actions/setup-python@v5 + with: + python-version: "{{ job_data.python_version }}" + + - name: Install tox + run: pip install tox + {%- if job_data.os == "windows-latest" %} + + - name: Configure git to support long filenames + run: git config --system core.longpaths true + {%- endif %} + + - name: Run tests + run: tox -e {{ job_data.tox_env }} -- -ra + {%- endfor %} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/version.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/version.py new file mode 100644 index 0000000000..3dc1f76bc6 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/version.py @@ -0,0 +1 @@ +__version__ = "0.1.0" diff --git a/.github/workflows/instrumentations_0.yml b/.github/workflows/instrumentations_0.yml deleted file mode 100644 index 382284d204..0000000000 --- a/.github/workflows/instrumentations_0.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: Contrib Repo Tests - -on: - push: - branches-ignore: - - 'release/*' - pull_request: -env: - CORE_REPO_SHA: main - -jobs: - instrumentations-0: - env: - # We use these variables to convert between tox and GHA version literals - py38: 3.8 - py39: 3.9 - py310: "3.10" - py311: "3.11" - py312: "3.12" - pypy3: pypy-3.8 - RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - python-version: [py38, py39, py310, py311, py312, pypy3] - package: - # Do not add more instrumentations here, add them in instrumentations_1.yml. - # The reason for this separation of instrumentations into more than one YAML file is - # the limit of jobs that can be run from a Github actions matrix: - # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs - # "A matrix will generate a maximum of 256 jobs per workflow run. This limit applies - # to both GitHub-hosted and self-hosted runners." - - "aiohttp-client" - - "aiohttp-server" - - "aiopg" - - "aio-pika" - - "asgi" - - "asyncpg" - - "aws-lambda" - - "boto" - - "boto3sqs" - - "botocore" - - "cassandra" - - "celery" - - "confluent-kafka" - - "dbapi" - - "django" - - "elasticsearch" - - "falcon" - - "fastapi" - - "flask" - - "grpc" - - "httpx" - - "jinja2" - - "kafka-python" - - "logging" - - "mysql" - - "mysqlclient" - - "sio-pika" - - "psycopg2" - - "pymemcache" - - "pymongo" - - "pymysql" - - "pyramid" - - "redis" - - "remoulade" - - "requests" - - "sqlalchemy" - - "sqlite3" - - "starlette" - - "system-metrics" - - "tornado" - - "tortoiseorm" - os: [ubuntu-20.04] - exclude: - - python-version: py312 - package: "boto" - - python-version: py312 - package: "kafka-python" - - python-version: pypy3 - package: "aiopg" - - python-version: pypy3 - package: "asyncpg" - - python-version: pypy3 - package: "boto" - - python-version: pypy3 - package: "boto3sqs" - - python-version: pypy3 - package: "botocore" - - python-version: pypy3 - package: "psycopg2" - - python-version: pypy3 - package: "remoulade" - - python-version: pypy3 - package: "requests" - - python-version: pypy3 - package: "confluent-kafka" - - python-version: pypy3 - package: "grpc" - steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - name: Set up Python ${{ env[matrix.python-version] }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env[matrix.python-version] }} - - name: Install tox - run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('gen-requirements.txt', 'dev-requirements.txt') }} - - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index b9f7a41c17..0000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: Lint tests - -on: - push: - branches-ignore: - - 'release/*' - pull_request: -env: - CORE_REPO_SHA: main - -jobs: - lint-3_12: - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - package: - - "distro" - - "exporter-prometheus-remote-write" - - "exporter-richconsole" - - "instrumentation-aio-pika" - - "instrumentation-aiohttp-client" - - "instrumentation-aiohttp-server" - - "instrumentation-aiopg" - - "instrumentation-asgi" - - "instrumentation-asyncio" - - "instrumentation-asyncpg" - - "instrumentation-aws-lambda" - - "instrumentation-boto" - - "instrumentation-boto3sqs" - - "instrumentation-botocore" - - "instrumentation-cassandra" - - "instrumentation-celery" - - "instrumentation-confluent-kafka" - - "instrumentation-dbapi" - - "instrumentation-django" - - "instrumentation-elasticsearch" - - "instrumentation-falcon" - - "instrumentation-fastapi" - - "instrumentation-flask" - - "instrumentation-grpc" - - "instrumentation-httpx" - - "instrumentation-jinja2" - - "instrumentation-kafka-python" - - "instrumentation-logging" - - "instrumentation-mysql" - - "instrumentation-mysqlclient" - - "instrumentation-psycopg" - - "instrumentation-psycopg2" - - "instrumentation-pymemcache" - - "instrumentation-pymongo" - - "instrumentation-pymysql" - - "instrumentation-pyramid" - - "instrumentation-redis" - - "instrumentation-remoulade" - - "instrumentation-requests" - - "instrumentation-sio-pika" - - "instrumentation-sqlalchemy" - - "instrumentation-sqlite3" - - "instrumentation-starlette" - - "instrumentation-system-metrics" - - "instrumentation-threading" - - "instrumentation-tornado" - - "instrumentation-tortoiseorm" - - "instrumentation-urllib" - - "instrumentation-urllib3" - - "instrumentation-wsgi" - - "opentelemetry-instrumentation" - - "processor-baggage" - - "propagator-aws-xray" - - "propagator-ot-trace" - - "resource-detector-azure" - - "resource-detector-container" - - "sdk-extension-aws" - - "util-http" - os: [ubuntu-20.04] - runs-on: ubuntu-20.04 - steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: 3.12 - - name: Install tox - run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v7-build-tox-cache-${{ matrix.package }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }} - - name: run tox - run: tox -e lint-${{ matrix.package }} diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml new file mode 100644 index 0000000000..b5d20541e5 --- /dev/null +++ b/.github/workflows/lint_0.yml @@ -0,0 +1,1061 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Lint 0 + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + lint-resource-detector-container: + name: resource-detector-container + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-resource-detector-container + + lint-resource-detector-azure: + name: resource-detector-azure + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-resource-detector-azure + + lint-sdk-extension-aws: + name: sdk-extension-aws + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-sdk-extension-aws + + lint-distro: + name: distro + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-distro + + lint-opentelemetry-instrumentation: + name: opentelemetry-instrumentation + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-opentelemetry-instrumentation + + lint-instrumentation-aiohttp-client: + name: instrumentation-aiohttp-client + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-aiohttp-client + + lint-instrumentation-aiohttp-server: + name: instrumentation-aiohttp-server + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-aiohttp-server + + lint-instrumentation-aiopg: + name: instrumentation-aiopg + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-aiopg + + lint-instrumentation-aws-lambda: + name: instrumentation-aws-lambda + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-aws-lambda + + lint-instrumentation-botocore: + name: instrumentation-botocore + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-botocore + + lint-instrumentation-boto3sqs: + name: instrumentation-boto3sqs + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-boto3sqs + + lint-instrumentation-django: + name: instrumentation-django + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-django + + lint-instrumentation-dbapi: + name: instrumentation-dbapi + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-dbapi + + lint-instrumentation-boto: + name: instrumentation-boto + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-boto + + lint-instrumentation-elasticsearch: + name: instrumentation-elasticsearch + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-elasticsearch + + lint-instrumentation-falcon: + name: instrumentation-falcon + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-falcon + + lint-instrumentation-fastapi: + name: instrumentation-fastapi + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-fastapi + + lint-instrumentation-flask: + name: instrumentation-flask + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-flask + + lint-instrumentation-urllib: + name: instrumentation-urllib + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-urllib + + lint-instrumentation-urllib3: + name: instrumentation-urllib3 + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-urllib3 + + lint-instrumentation-requests: + name: instrumentation-requests + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-requests + + lint-instrumentation-starlette: + name: instrumentation-starlette + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-starlette + + lint-instrumentation-jinja2: + name: instrumentation-jinja2 + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-jinja2 + + lint-instrumentation-logging: + name: instrumentation-logging + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-logging + + lint-exporter-richconsole: + name: exporter-richconsole + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-exporter-richconsole + + lint-exporter-prometheus-remote-write: + name: exporter-prometheus-remote-write + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-exporter-prometheus-remote-write + + lint-instrumentation-mysql: + name: instrumentation-mysql + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-mysql + + lint-instrumentation-mysqlclient: + name: instrumentation-mysqlclient + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-mysqlclient + + lint-instrumentation-psycopg2: + name: instrumentation-psycopg2 + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-psycopg2 + + lint-instrumentation-psycopg: + name: instrumentation-psycopg + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-psycopg + + lint-instrumentation-pymemcache: + name: instrumentation-pymemcache + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-pymemcache + + lint-instrumentation-pymongo: + name: instrumentation-pymongo + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-pymongo + + lint-instrumentation-pymysql: + name: instrumentation-pymysql + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-pymysql + + lint-instrumentation-pyramid: + name: instrumentation-pyramid + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-pyramid + + lint-instrumentation-asgi: + name: instrumentation-asgi + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-asgi + + lint-instrumentation-asyncpg: + name: instrumentation-asyncpg + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-asyncpg + + lint-instrumentation-sqlite3: + name: instrumentation-sqlite3 + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-sqlite3 + + lint-instrumentation-wsgi: + name: instrumentation-wsgi + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-wsgi + + lint-instrumentation-grpc: + name: instrumentation-grpc + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-grpc + + lint-instrumentation-sqlalchemy: + name: instrumentation-sqlalchemy + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-sqlalchemy + + lint-instrumentation-redis: + name: instrumentation-redis + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-redis + + lint-instrumentation-remoulade: + name: instrumentation-remoulade + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-remoulade + + lint-instrumentation-celery: + name: instrumentation-celery + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-celery + + lint-instrumentation-system-metrics: + name: instrumentation-system-metrics + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-system-metrics + + lint-instrumentation-threading: + name: instrumentation-threading + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-threading + + lint-instrumentation-tornado: + name: instrumentation-tornado + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-tornado + + lint-instrumentation-tortoiseorm: + name: instrumentation-tortoiseorm + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-tortoiseorm + + lint-instrumentation-httpx: + name: instrumentation-httpx + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-httpx + + lint-util-http: + name: util-http + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-util-http + + lint-propagator-aws-xray: + name: propagator-aws-xray + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-propagator-aws-xray + + lint-propagator-ot-trace: + name: propagator-ot-trace + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-propagator-ot-trace + + lint-instrumentation-sio-pika: + name: instrumentation-sio-pika + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-sio-pika + + lint-instrumentation-aio-pika: + name: instrumentation-aio-pika + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-aio-pika + + lint-instrumentation-kafka-python: + name: instrumentation-kafka-python + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-kafka-python + + lint-instrumentation-confluent-kafka: + name: instrumentation-confluent-kafka + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-confluent-kafka + + lint-instrumentation-asyncio: + name: instrumentation-asyncio + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-asyncio + + lint-instrumentation-cassandra: + name: instrumentation-cassandra + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-cassandra + + lint-processor-baggage: + name: processor-baggage + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-processor-baggage diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml new file mode 100644 index 0000000000..f7b9faa9f3 --- /dev/null +++ b/.github/workflows/misc_0.yml @@ -0,0 +1,129 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Misc 0 + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + spellcheck: + name: spellcheck + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e spellcheck + + docker-tests: + name: docker-tests + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e docker-tests + + docs: + name: docs + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e docs + + generate: + name: generate + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e generate + + - name: Check workflows are up to date + run: git diff --exit-code || (echo 'Generated code is out of date, run "tox -e generate" and commit the changes in this PR.' && exit 1) + + generate-workflows: + name: generate-workflows + runs-on: ubuntu-latest + if: | + !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') + && github.actor != 'opentelemetrybot' + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e generate-workflows + + - name: Check workflows are up to date + run: git diff --exit-code || (echo 'Generated workflows are out of date, run "tox -e generate-workflows" and commit the changes in this PR.' && exit 1) + + shellcheck: + name: shellcheck + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e shellcheck diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml deleted file mode 100644 index 68d12b805f..0000000000 --- a/.github/workflows/shellcheck.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Shellcheck - -on: - push: - branches-ignore: - - 'release/*' - pull_request: - -jobs: - shellcheck: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install shellcheck - run: sudo apt update && sudo apt install --assume-yes shellcheck - - - name: Run shellcheck - run: find . -name \*.sh | xargs shellcheck --severity=warning diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 2714942c21..0000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Contrib Repo Tests - -on: - push: - branches-ignore: - - 'release/*' - pull_request: -env: - CORE_REPO_SHA: main - -jobs: - misc: - strategy: - fail-fast: false - matrix: - tox-environment: [ "docker-tests", "spellcheck", "docs", "generate" ] - name: ${{ matrix.tox-environment }} - runs-on: ubuntu-20.04 - steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - name: Install tox - run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v7-misc-tox-cache-${{ matrix.tox-environment }}-${{ hashFiles('tox.ini', 'dev-requirements.txt', 'gen-requirements.txt', 'docs-requirements.txt') }} - - name: run tox - run: tox -e ${{ matrix.tox-environment }} - - name: Ensure generated code is up to date - if: matrix.tox-environment == 'generate' - run: git diff --exit-code || (echo 'Generated code is out of date, please run "tox -e generate" and commit the changes in this PR.' && exit 1) diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml new file mode 100644 index 0000000000..ec189c09b1 --- /dev/null +++ b/.github/workflows/test_0.yml @@ -0,0 +1,4517 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Test 0 + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + py38-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-resource-detector-container -- -ra + + py39-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-resource-detector-container -- -ra + + py310-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-resource-detector-container -- -ra + + py311-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-resource-detector-container -- -ra + + py312-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-resource-detector-container -- -ra + + pypy3-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-resource-detector-container -- -ra + + py38-test-resource-detector-azure_ubuntu-latest: + name: resource-detector-azure 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-resource-detector-azure -- -ra + + py39-test-resource-detector-azure_ubuntu-latest: + name: resource-detector-azure 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-resource-detector-azure -- -ra + + py310-test-resource-detector-azure_ubuntu-latest: + name: resource-detector-azure 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-resource-detector-azure -- -ra + + py311-test-resource-detector-azure_ubuntu-latest: + name: resource-detector-azure 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-resource-detector-azure -- -ra + + py312-test-resource-detector-azure_ubuntu-latest: + name: resource-detector-azure 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-resource-detector-azure -- -ra + + pypy3-test-resource-detector-azure_ubuntu-latest: + name: resource-detector-azure pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-resource-detector-azure -- -ra + + py38-test-sdk-extension-aws_ubuntu-latest: + name: sdk-extension-aws 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-sdk-extension-aws -- -ra + + py39-test-sdk-extension-aws_ubuntu-latest: + name: sdk-extension-aws 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-sdk-extension-aws -- -ra + + py310-test-sdk-extension-aws_ubuntu-latest: + name: sdk-extension-aws 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-sdk-extension-aws -- -ra + + py311-test-sdk-extension-aws_ubuntu-latest: + name: sdk-extension-aws 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-sdk-extension-aws -- -ra + + py312-test-sdk-extension-aws_ubuntu-latest: + name: sdk-extension-aws 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-sdk-extension-aws -- -ra + + pypy3-test-sdk-extension-aws_ubuntu-latest: + name: sdk-extension-aws pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-sdk-extension-aws -- -ra + + py38-test-distro_ubuntu-latest: + name: distro 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-distro -- -ra + + py39-test-distro_ubuntu-latest: + name: distro 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-distro -- -ra + + py310-test-distro_ubuntu-latest: + name: distro 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-distro -- -ra + + py311-test-distro_ubuntu-latest: + name: distro 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-distro -- -ra + + py312-test-distro_ubuntu-latest: + name: distro 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-distro -- -ra + + pypy3-test-distro_ubuntu-latest: + name: distro pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-distro -- -ra + + py38-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-opentelemetry-instrumentation -- -ra + + py39-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-opentelemetry-instrumentation -- -ra + + py310-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-opentelemetry-instrumentation -- -ra + + py311-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-opentelemetry-instrumentation -- -ra + + py312-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-opentelemetry-instrumentation -- -ra + + pypy3-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-opentelemetry-instrumentation -- -ra + + py38-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiohttp-client -- -ra + + py39-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aiohttp-client -- -ra + + py310-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aiohttp-client -- -ra + + py311-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aiohttp-client -- -ra + + py312-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aiohttp-client -- -ra + + pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra + + py38-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiohttp-server -- -ra + + py39-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aiohttp-server -- -ra + + py310-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aiohttp-server -- -ra + + py311-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aiohttp-server -- -ra + + py312-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aiohttp-server -- -ra + + pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra + + py38-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiopg -- -ra + + py39-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aiopg -- -ra + + py310-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aiopg -- -ra + + py311-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aiopg -- -ra + + py312-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aiopg -- -ra + + py38-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aws-lambda -- -ra + + py39-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aws-lambda -- -ra + + py310-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aws-lambda -- -ra + + py311-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aws-lambda -- -ra + + py312-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aws-lambda -- -ra + + pypy3-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra + + py38-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-botocore -- -ra + + py39-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore -- -ra + + py310-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore -- -ra + + py311-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore -- -ra + + py312-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore -- -ra + + py38-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-boto3sqs -- -ra + + py39-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-boto3sqs -- -ra + + py310-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-boto3sqs -- -ra + + py311-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-boto3sqs -- -ra + + py312-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-boto3sqs -- -ra + + pypy3-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra + + py38-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-django-0 -- -ra + + py38-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-django-1 -- -ra + + py38-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-django-2 -- -ra + + py39-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-django-0 -- -ra + + py39-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-django-1 -- -ra + + py39-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-django-2 -- -ra + + py310-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-django-1 -- -ra + + py310-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-django-3 -- -ra + + py311-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-django-1 -- -ra + + py311-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-django-3 -- -ra + + py312-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-django-1 -- -ra + + py312-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-django-3 -- -ra + + pypy3-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-django-0 -- -ra + + pypy3-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-django-1 -- -ra + + py38-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-dbapi -- -ra + + py39-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-dbapi -- -ra + + py310-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-dbapi -- -ra + + py311-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-dbapi -- -ra + + py312-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-dbapi -- -ra + + pypy3-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-dbapi -- -ra + + py38-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-boto -- -ra + + py39-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-boto -- -ra + + py310-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-boto -- -ra + + py311-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-boto -- -ra + + py38-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra + + py38-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra + + py38-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra + + py39-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + + py39-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + + py39-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra + + py310-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra + + py310-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra + + py310-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra + + py311-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra + + py311-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra + + py311-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra + + py312-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra + + py312-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra + + py312-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra + + pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra + + pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra + + pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra + + py38-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-0 -- -ra + + py38-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-1 -- -ra + + py38-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-2 -- -ra + + py39-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-0 -- -ra + + py39-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-1 -- -ra + + py39-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-2 -- -ra + + py310-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-1 -- -ra + + py310-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-2 -- -ra + + py311-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-1 -- -ra + + py311-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-2 -- -ra + + py312-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-1 -- -ra + + py312-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-2 -- -ra + + pypy3-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra + + pypy3-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra + + pypy3-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra + + py38-test-instrumentation-fastapi-main_ubuntu-latest: + name: instrumentation-fastapi-main 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-fastapi-main -- -ra + + py38-test-instrumentation-fastapi-slim_ubuntu-latest: + name: instrumentation-fastapi-slim 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-fastapi-slim -- -ra + + py39-test-instrumentation-fastapi-main_ubuntu-latest: + name: instrumentation-fastapi-main 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-fastapi-main -- -ra + + py39-test-instrumentation-fastapi-slim_ubuntu-latest: + name: instrumentation-fastapi-slim 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-fastapi-slim -- -ra + + py310-test-instrumentation-fastapi-main_ubuntu-latest: + name: instrumentation-fastapi-main 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-fastapi-main -- -ra + + py310-test-instrumentation-fastapi-slim_ubuntu-latest: + name: instrumentation-fastapi-slim 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-fastapi-slim -- -ra + + py311-test-instrumentation-fastapi-main_ubuntu-latest: + name: instrumentation-fastapi-main 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-fastapi-main -- -ra + + py311-test-instrumentation-fastapi-slim_ubuntu-latest: + name: instrumentation-fastapi-slim 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-fastapi-slim -- -ra + + py312-test-instrumentation-fastapi-main_ubuntu-latest: + name: instrumentation-fastapi-main 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-fastapi-main -- -ra + + py312-test-instrumentation-fastapi-slim_ubuntu-latest: + name: instrumentation-fastapi-slim 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-fastapi-slim -- -ra + + pypy3-test-instrumentation-fastapi-main_ubuntu-latest: + name: instrumentation-fastapi-main pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-fastapi-main -- -ra + + pypy3-test-instrumentation-fastapi-slim_ubuntu-latest: + name: instrumentation-fastapi-slim pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-fastapi-slim -- -ra + + py38-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-0 -- -ra + + py38-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-1 -- -ra + + py39-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-0 -- -ra + + py39-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-1 -- -ra + + py310-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-0 -- -ra + + py310-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-1 -- -ra + + py311-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-0 -- -ra + + py311-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-1 -- -ra + + py312-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-0 -- -ra + + py312-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-1 -- -ra + + py38-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-2 -- -ra + + py39-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-2 -- -ra + + py310-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-2 -- -ra + + py311-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-2 -- -ra + + py312-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-2 -- -ra + + pypy3-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-flask-0 -- -ra + + pypy3-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-flask-1 -- -ra + + py38-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-urllib -- -ra + + py39-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-urllib -- -ra + + py310-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-urllib -- -ra + + py311-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-urllib -- -ra + + py312-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-urllib -- -ra + + pypy3-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib -- -ra + + py38-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-urllib3-0 -- -ra + + py38-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-urllib3-1 -- -ra + + py39-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + + py39-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + + py310-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra + + py310-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra + + py311-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + + py311-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-urllib3-1 -- -ra + + py312-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-urllib3-0 -- -ra + + py312-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-urllib3-1 -- -ra + + pypy3-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra + + pypy3-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra + + py38-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-requests -- -ra + + py39-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-requests -- -ra + + py310-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-requests -- -ra + + py311-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-requests -- -ra + + py312-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-requests -- -ra + + py38-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-starlette -- -ra + + py39-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-starlette -- -ra + + py310-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-starlette -- -ra + + py311-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-starlette -- -ra + + py312-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-starlette -- -ra + + pypy3-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-starlette -- -ra + + py38-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-jinja2 -- -ra + + py39-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-jinja2 -- -ra + + py310-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-jinja2 -- -ra + + py311-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-jinja2 -- -ra + + py312-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-jinja2 -- -ra + + pypy3-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-jinja2 -- -ra + + py38-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-logging -- -ra + + py39-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-logging -- -ra + + py310-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-logging -- -ra + + py311-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-logging -- -ra + + py312-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-logging -- -ra + + pypy3-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-logging -- -ra + + py38-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-exporter-richconsole -- -ra + + py39-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-exporter-richconsole -- -ra + + py310-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-exporter-richconsole -- -ra + + py311-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-exporter-richconsole -- -ra + + py312-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-exporter-richconsole -- -ra + + pypy3-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-exporter-richconsole -- -ra + + py38-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-exporter-prometheus-remote-write -- -ra + + py39-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-exporter-prometheus-remote-write -- -ra + + py310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra + + py311-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-exporter-prometheus-remote-write -- -ra + + py312-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-exporter-prometheus-remote-write -- -ra + + pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra + + py38-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysql-0 -- -ra + + py38-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysql-1 -- -ra + + py39-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-mysql-0 -- -ra + + py39-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-mysql-1 -- -ra + + py310-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-mysql-0 -- -ra + + py310-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-mysql-1 -- -ra + + py311-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-mysql-0 -- -ra + + py311-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-mysql-1 -- -ra + + py312-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-mysql-0 -- -ra + + py312-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-mysql-1 -- -ra + + pypy3-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra + + pypy3-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + + py38-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysqlclient -- -ra + + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-mysqlclient -- -ra + + py310-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-mysqlclient -- -ra + + py311-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-mysqlclient -- -ra + + py312-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-mysqlclient -- -ra + + pypy3-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra + + py38-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg2 -- -ra + + py39-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg2 -- -ra + + py310-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg2 -- -ra + + py311-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg2 -- -ra + + py312-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg2 -- -ra + + py38-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg -- -ra + + py39-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg -- -ra + + py310-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg -- -ra + + py311-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg -- -ra + + py312-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg -- -ra + + pypy3-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-psycopg -- -ra + + py38-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra + + py38-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra + + py38-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra + + py38-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra + + py38-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra + + py39-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + + py39-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + + py39-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + + py39-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + + py39-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra + + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra + + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra + + py310-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra + + py310-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra + + py311-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra + + py311-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra + + py311-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml new file mode 100644 index 0000000000..e1ce8cd445 --- /dev/null +++ b/.github/workflows/test_1.yml @@ -0,0 +1,3797 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Test 1 + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + py311-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra + + py311-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra + + py312-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra + + py312-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra + + py312-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + + py312-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra + + py312-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra + + pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra + + pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra + + pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra + + pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra + + pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra + + py38-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymongo -- -ra + + py39-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymongo -- -ra + + py310-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymongo -- -ra + + py311-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymongo -- -ra + + py312-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymongo -- -ra + + pypy3-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymongo -- -ra + + py38-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymysql -- -ra + + py39-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymysql -- -ra + + py310-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymysql -- -ra + + py311-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymysql -- -ra + + py312-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymysql -- -ra + + pypy3-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymysql -- -ra + + py38-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pyramid -- -ra + + py39-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pyramid -- -ra + + py310-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pyramid -- -ra + + py311-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pyramid -- -ra + + py312-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pyramid -- -ra + + pypy3-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pyramid -- -ra + + py38-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asgi -- -ra + + py39-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-asgi -- -ra + + py310-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-asgi -- -ra + + py311-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-asgi -- -ra + + py312-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-asgi -- -ra + + pypy3-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-asgi -- -ra + + py38-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asyncpg -- -ra + + py39-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncpg -- -ra + + py310-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncpg -- -ra + + py311-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncpg -- -ra + + py312-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncpg -- -ra + + py38-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sqlite3 -- -ra + + py39-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlite3 -- -ra + + py310-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlite3 -- -ra + + py311-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlite3 -- -ra + + py312-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlite3 -- -ra + + pypy3-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra + + py38-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-wsgi -- -ra + + py39-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-wsgi -- -ra + + py310-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-wsgi -- -ra + + py311-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-wsgi -- -ra + + py312-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-wsgi -- -ra + + pypy3-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-wsgi -- -ra + + py38-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-grpc-0 -- -ra + + py38-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-grpc-1 -- -ra + + py39-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-0 -- -ra + + py39-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-1 -- -ra + + py310-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-grpc-0 -- -ra + + py310-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-grpc-1 -- -ra + + py311-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-grpc-0 -- -ra + + py311-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-grpc-1 -- -ra + + py312-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-grpc-0 -- -ra + + py312-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-grpc-1 -- -ra + + py38-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra + + py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + + py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra + + py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra + + py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra + + pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: + name: instrumentation-sqlalchemy-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra + + pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra + + py38-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-redis -- -ra + + py39-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-redis -- -ra + + py310-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-redis -- -ra + + py311-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-redis -- -ra + + py312-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-redis -- -ra + + pypy3-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-redis -- -ra + + py38-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-remoulade -- -ra + + py39-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-remoulade -- -ra + + py310-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-remoulade -- -ra + + py311-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-remoulade -- -ra + + py312-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-remoulade -- -ra + + py38-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-celery -- -ra + + py39-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-celery -- -ra + + py310-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-celery -- -ra + + py311-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-celery -- -ra + + py312-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-celery -- -ra + + pypy3-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-celery -- -ra + + py38-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-system-metrics -- -ra + + py39-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-system-metrics -- -ra + + py310-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-system-metrics -- -ra + + py311-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-system-metrics -- -ra + + py312-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-system-metrics -- -ra + + pypy3-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-system-metrics -- -ra + + py38-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-threading -- -ra + + py39-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-threading -- -ra + + py310-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-threading -- -ra + + py311-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-threading -- -ra + + py312-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-threading -- -ra + + pypy3-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-threading -- -ra + + py38-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-tornado -- -ra + + py39-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-tornado -- -ra + + py310-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-tornado -- -ra + + py311-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-tornado -- -ra + + py312-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-tornado -- -ra + + pypy3-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-tornado -- -ra + + py38-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-tortoiseorm -- -ra + + py39-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-tortoiseorm -- -ra + + py310-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-tortoiseorm -- -ra + + py311-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-tortoiseorm -- -ra + + py312-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-tortoiseorm -- -ra + + pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra + + py38-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-httpx-0 -- -ra + + py38-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-httpx-1 -- -ra + + py39-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-0 -- -ra + + py39-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-1 -- -ra + + py310-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-httpx-0 -- -ra + + py310-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-httpx-1 -- -ra + + py311-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-httpx-0 -- -ra + + py311-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-httpx-1 -- -ra + + py312-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-httpx-0 -- -ra + + py312-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-httpx-1 -- -ra + + pypy3-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-httpx-0 -- -ra + + pypy3-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-httpx-1 -- -ra + + py38-test-util-http_ubuntu-latest: + name: util-http 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-util-http -- -ra + + py39-test-util-http_ubuntu-latest: + name: util-http 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-util-http -- -ra + + py310-test-util-http_ubuntu-latest: + name: util-http 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-util-http -- -ra + + py311-test-util-http_ubuntu-latest: + name: util-http 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-util-http -- -ra + + py312-test-util-http_ubuntu-latest: + name: util-http 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-util-http -- -ra + + pypy3-test-util-http_ubuntu-latest: + name: util-http pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-util-http -- -ra + + py38-test-propagator-aws-xray_ubuntu-latest: + name: propagator-aws-xray 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-aws-xray -- -ra + + py39-test-propagator-aws-xray_ubuntu-latest: + name: propagator-aws-xray 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray -- -ra + + py310-test-propagator-aws-xray_ubuntu-latest: + name: propagator-aws-xray 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray -- -ra + + py311-test-propagator-aws-xray_ubuntu-latest: + name: propagator-aws-xray 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray -- -ra + + py312-test-propagator-aws-xray_ubuntu-latest: + name: propagator-aws-xray 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray -- -ra + + pypy3-test-propagator-aws-xray_ubuntu-latest: + name: propagator-aws-xray pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray -- -ra + + py38-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-ot-trace -- -ra + + py39-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-propagator-ot-trace -- -ra + + py310-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-propagator-ot-trace -- -ra + + py311-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-propagator-ot-trace -- -ra + + py312-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-propagator-ot-trace -- -ra + + pypy3-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-propagator-ot-trace -- -ra + + py38-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sio-pika-0 -- -ra + + py38-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sio-pika-1 -- -ra + + py39-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0 -- -ra + + py39-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-1 -- -ra + + py310-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-0 -- -ra + + py310-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-1 -- -ra + + py311-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-0 -- -ra + + py311-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-1 -- -ra + + py312-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-0 -- -ra + + py312-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-1 -- -ra + + pypy3-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-0 -- -ra + + pypy3-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-1 -- -ra + + py38-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-0 -- -ra + + py38-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-1 -- -ra + + py38-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-2 -- -ra + + py38-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-3 -- -ra + + py39-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + + py39-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + + py39-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + + py39-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + + py310-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra + + py310-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra + + py310-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra + + py310-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra + + py311-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra + + py311-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra + + py311-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra + + py311-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra + + py312-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra + + py312-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra + + py312-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra + + py312-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra + + pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra + + pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra + + pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra + + pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra + + py38-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-kafka-python -- -ra + + py39-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-kafka-python -- -ra + + py310-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-kafka-python -- -ra + + py311-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-kafka-python -- -ra + + py38-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-kafka-pythonng -- -ra + + py39-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + + py310-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra + + py311-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra + + py312-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra + + pypy3-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-kafka-python -- -ra + + pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra + + py38-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-confluent-kafka -- -ra + + py39-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-confluent-kafka -- -ra + + py310-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-confluent-kafka -- -ra + + py311-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-confluent-kafka -- -ra + + py312-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-confluent-kafka -- -ra + + py38-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asyncio -- -ra + + py39-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncio -- -ra + + py310-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncio -- -ra + + py311-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncio -- -ra + + py312-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncio -- -ra + + py38-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-cassandra -- -ra + + py39-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-cassandra -- -ra + + py310-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-cassandra -- -ra + + py311-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-cassandra -- -ra + + py312-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-cassandra -- -ra + + pypy3-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-cassandra -- -ra + + py38-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-processor-baggage -- -ra + + py39-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-processor-baggage -- -ra + + py310-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-processor-baggage -- -ra + + py311-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-processor-baggage -- -ra + + py312-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-processor-baggage -- -ra + + pypy3-test-processor-baggage_ubuntu-latest: + name: processor-baggage pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-processor-baggage -- -ra diff --git a/tox.ini b/tox.ini index faa50aa711..75e8a7f5a0 100644 --- a/tox.ini +++ b/tox.ini @@ -73,11 +73,8 @@ envlist = ; 1: django~=3.0 ; 2: django>=4.0b1,<5.0 backports.zoneinfo==0.2.1 ; 3: django>=4.0b1,<5.0 - py3{8,9}-test-instrumentation-django-0 - py3{8,9}-test-instrumentation-django-1 - py3{8,9}-test-instrumentation-django-2 - py3{10,11,12}-test-instrumentation-django-1 - py3{10,11,12}-test-instrumentation-django-3 + py3{8,9}-test-instrumentation-django-{0,1,2} + py3{10,11,12}-test-instrumentation-django-{1,3} pypy3-test-instrumentation-django-{0,1} lint-instrumentation-django @@ -109,8 +106,8 @@ envlist = ; 0: falcon ==1.4.1 ; 1: falcon >=2.0.0,<3.0.0 ; 2: falcon >=3.0.0,<4.0.0 - py3{8,9}-test-instrumentation-falcon-0 - py3{8,9,10,11,12}-test-instrumentation-falcon-{1,2} + py3{8,9}-test-instrumentation-falcon-{0,1,2} + py3{10,11,12}-test-instrumentation-falcon-{1,2} pypy3-test-instrumentation-falcon-{0,1,2} lint-instrumentation-falcon @@ -254,7 +251,6 @@ envlist = ; 0: grpcio==1.62.0 ; 1: grpcio==1.63.0 py3{8,9,10,11,12}-test-instrumentation-grpc-{0,1} - pypy3-test-instrumentation-grpc-{0,1} lint-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy @@ -355,7 +351,6 @@ envlist = ; opentelemetry-instrumentation-confluent-kafka py3{8,9,10,11,12}-test-instrumentation-confluent-kafka - pypy3-test-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka ; opentelemetry-instrumentation-asyncio @@ -376,8 +371,9 @@ envlist = spellcheck docker-tests docs - generate + generate-workflows + shellcheck [testenv] deps = @@ -387,7 +383,8 @@ deps = ; FIXME: add coverage testing ; FIXME: add mypy testing -allowlist_externals = sh +allowlist_externals = + sh setenv = ; override CORE_REPO_SHA via env variable when testing other branches/commits than main @@ -1318,3 +1315,19 @@ commands = {toxinidir}/scripts/generate_instrumentation_bootstrap.py {toxinidir}/scripts/generate_instrumentation_readme.py {toxinidir}/scripts/generate_instrumentation_metapackage.py + +[testenv:generate-workflows] + +commands_pre = + pip install {toxinidir}/.github/workflows/generate_workflows_lib + +commands = + python {toxinidir}/.github/workflows/generate_workflows.py + +[testenv:shellcheck] + +commands_pre = + sh -c "sudo apt update -y && sudo apt install --assume-yes shellcheck" + +commands = + sh -c "find {toxinidir} -name \*.sh | xargs shellcheck --severity=warning" From 009bdbaef0d4eb6ab6de992cdfbfebb05ef8a51b Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 6 Aug 2024 16:41:00 -0600 Subject: [PATCH 143/335] Remove instrumentations_1.yml (#2782) Fixes #2781 --- .github/workflows/instrumentations_1.yml | 65 ------------------------ 1 file changed, 65 deletions(-) delete mode 100644 .github/workflows/instrumentations_1.yml diff --git a/.github/workflows/instrumentations_1.yml b/.github/workflows/instrumentations_1.yml deleted file mode 100644 index c020b972eb..0000000000 --- a/.github/workflows/instrumentations_1.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Contrib Repo Tests - -on: - push: - branches-ignore: - - 'release/*' - pull_request: -env: - CORE_REPO_SHA: main - -jobs: - instrumentations-1: - env: - # We use these variables to convert between tox and GHA version literals - py38: 3.8 - py39: 3.9 - py310: "3.10" - py311: "3.11" - py312: "3.12" - pypy3: pypy-3.8 - RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - python-version: [py38, py39, py310, py311, py312, pypy3] - package: - - "urllib" - - "urllib3" - - "wsgi" - - "distro" - - "richconsole" - - "psycopg" - - "prometheus-remote-write" - - "sdk-extension-aws" - - "propagator-aws-xray" - - "propagator-ot-trace" - - "resource-detector-azure" - - "resource-detector-container" - - "util-http" - - "processor-baggage" - - "kafka-pythonng" - os: [ubuntu-20.04] - exclude: - - python-version: pypy3 - package: "prometheus-remote-write" - steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - name: Set up Python ${{ env[matrix.python-version] }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env[matrix.python-version] }} - - name: Install tox - run: pip install tox - - name: Cache tox environment - # Preserves .tox directory between runs for faster installs - uses: actions/cache@v4 - with: - path: | - .tox - ~/.cache/pip - key: v7-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('gen-requirements.txt', 'dev-requirements.txt') }} - - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- -ra From fc1c8f0f3f0554ffffc1accb3ffb9b74e2af7072 Mon Sep 17 00:00:00 2001 From: Qiu Ge Date: Wed, 7 Aug 2024 23:41:01 +0800 Subject: [PATCH 144/335] Audit and test opentelemetry-instrumentation-fastapi NoOpTracerProvider (#2779) --- .../tests/test_fastapi_instrumentation.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 03fdd6749d..91ed514096 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -1069,6 +1069,18 @@ def test_uninstrument_after_instrument(self): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 3) + def test_no_op_tracer_provider(self): + self._instrumentor.uninstrument() + self._instrumentor.instrument( + tracer_provider=trace.NoOpTracerProvider() + ) + + app = self._create_fastapi_app() + client = TestClient(app) + client.get("/foobar") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + def tearDown(self): self._instrumentor.uninstrument() super().tearDown() From c238af5442e89a5a77496c9f5aa2217e1812b13e Mon Sep 17 00:00:00 2001 From: Radoslav Kirilov Date: Thu, 8 Aug 2024 18:45:00 +0300 Subject: [PATCH 145/335] fix: `fastapi` auto-instrumentation by removing `fastapi-slim` support (#2783) --- .github/workflows/test_0.yml | 252 +++++++++--------- .github/workflows/test_1.yml | 108 -------- CHANGELOG.md | 4 +- instrumentation/README.md | 2 +- .../pyproject.toml | 1 - .../instrumentation/fastapi/__init__.py | 22 +- .../instrumentation/fastapi/package.py | 5 +- .../test-requirements-slim.txt | 32 --- .../instrumentation/bootstrap_gen.py | 4 - tox.ini | 8 +- 10 files changed, 134 insertions(+), 304 deletions(-) delete mode 100644 instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index ec189c09b1..d251737227 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -2194,8 +2194,8 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra - py38-test-instrumentation-fastapi-main_ubuntu-latest: - name: instrumentation-fastapi-main 3.8 Ubuntu + py38-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2210,28 +2210,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-fastapi-main -- -ra + run: tox -e py38-test-instrumentation-fastapi -- -ra - py38-test-instrumentation-fastapi-slim_ubuntu-latest: - name: instrumentation-fastapi-slim 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-fastapi-slim -- -ra - - py39-test-instrumentation-fastapi-main_ubuntu-latest: - name: instrumentation-fastapi-main 3.9 Ubuntu + py39-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2246,46 +2228,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-fastapi-main -- -ra - - py39-test-instrumentation-fastapi-slim_ubuntu-latest: - name: instrumentation-fastapi-slim 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-fastapi-slim -- -ra - - py310-test-instrumentation-fastapi-main_ubuntu-latest: - name: instrumentation-fastapi-main 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-fastapi-main -- -ra + run: tox -e py39-test-instrumentation-fastapi -- -ra - py310-test-instrumentation-fastapi-slim_ubuntu-latest: - name: instrumentation-fastapi-slim 3.10 Ubuntu + py310-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2300,10 +2246,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-fastapi-slim -- -ra + run: tox -e py310-test-instrumentation-fastapi -- -ra - py311-test-instrumentation-fastapi-main_ubuntu-latest: - name: instrumentation-fastapi-main 3.11 Ubuntu + py311-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2318,28 +2264,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-fastapi-main -- -ra + run: tox -e py311-test-instrumentation-fastapi -- -ra - py311-test-instrumentation-fastapi-slim_ubuntu-latest: - name: instrumentation-fastapi-slim 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-fastapi-slim -- -ra - - py312-test-instrumentation-fastapi-main_ubuntu-latest: - name: instrumentation-fastapi-main 3.12 Ubuntu + py312-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2354,46 +2282,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-fastapi-main -- -ra - - py312-test-instrumentation-fastapi-slim_ubuntu-latest: - name: instrumentation-fastapi-slim 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-fastapi-slim -- -ra - - pypy3-test-instrumentation-fastapi-main_ubuntu-latest: - name: instrumentation-fastapi-main pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-fastapi-main -- -ra + run: tox -e py312-test-instrumentation-fastapi -- -ra - pypy3-test-instrumentation-fastapi-slim_ubuntu-latest: - name: instrumentation-fastapi-slim pypy-3.8 Ubuntu + pypy3-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2408,7 +2300,7 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-fastapi-slim -- -ra + run: tox -e pypy3-test-instrumentation-fastapi -- -ra py38-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 3.8 Ubuntu @@ -4515,3 +4407,111 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra + + py311-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra + + py311-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra + + py312-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra + + py312-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra + + py312-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + + py312-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index e1ce8cd445..f7e71dd6b6 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,114 +16,6 @@ env: jobs: - py311-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra - - py311-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra - - py312-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra - - py312-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra - - py312-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra - - py312-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra - py312-test-instrumentation-pymemcache-4_ubuntu-latest: name: instrumentation-pymemcache-4 3.12 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index e3b91462ba..49b66f69df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,14 +17,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Fixed +- `opentelemetry-instrumentation-fastapi` fix `fastapi` auto-instrumentation by removing `fastapi-slim` support, `fastapi-slim` itself is discontinued from maintainers + ([2783](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2783)) - `opentelemetry-instrumentation-aws-lambda` Avoid exception when a handler is not present. ([#2750](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2750)) - `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics ([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746)) - `opentelemetry-instrumentation-grpc` Fixes the issue with the gRPC instrumentation not working with the 1.63.0 and higher version of gRPC ([#2483](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2484)) -- `opentelemetry-instrumentation-fastapi` Fix fastapi-slim support - ([#2756](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2756)) - `opentelemetry-instrumentation-aws-lambda` Fixing w3c baggage support ([#2589](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2589)) - `opentelemetry-instrumentation-celery` propagates baggage diff --git a/instrumentation/README.md b/instrumentation/README.md index 378497db79..22c4241bab 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -19,7 +19,7 @@ | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental | [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 4.0.0 | Yes | experimental -| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58,fastapi-slim ~= 0.111 | Yes | migration +| [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental | [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index eec5b0f10f..3017dc040a 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -35,7 +35,6 @@ dependencies = [ [project.optional-dependencies] instruments = [ "fastapi ~= 0.58", - "fastapi-slim ~= 0.111", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index fdb035baa8..37a293764e 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -179,7 +179,6 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from __future__ import annotations import logging -from importlib.metadata import PackageNotFoundError, distribution from typing import Collection import fastapi @@ -197,11 +196,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A ClientResponseHook, ServerRequestHook, ) -from opentelemetry.instrumentation.fastapi.package import ( - _fastapi, - _fastapi_slim, - _instruments, -) +from opentelemetry.instrumentation.fastapi.package import _instruments from opentelemetry.instrumentation.fastapi.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.metrics import get_meter @@ -298,21 +293,6 @@ def uninstrument_app(app: fastapi.FastAPI): app._is_instrumented_by_opentelemetry = False def instrumentation_dependencies(self) -> Collection[str]: - # need to use distribution because find_spec("fastapi") will return - # something even with just fastapi-slim installed - try: - distribution("fastapi-slim") - return (_fastapi_slim,) - except PackageNotFoundError: - pass - - try: - distribution("fastapi") - return (_fastapi,) - except PackageNotFoundError: - pass - - # If neither is installed, return both as potential dependencies return _instruments def _instrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py index 55cf4b3646..d95a2cf6d5 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/package.py @@ -13,10 +13,7 @@ # limitations under the License. -_fastapi = "fastapi ~= 0.58" -_fastapi_slim = "fastapi-slim ~= 0.111" - -_instruments = (_fastapi, _fastapi_slim) +_instruments = ("fastapi ~= 0.58",) _supports_metrics = True diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt deleted file mode 100644 index 2ea55f1b91..0000000000 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt +++ /dev/null @@ -1,32 +0,0 @@ -annotated-types==0.6.0 -anyio==4.3.0 -asgiref==3.7.2 -certifi==2024.7.4 -charset-normalizer==3.3.2 -Deprecated==1.2.14 -exceptiongroup==1.2.0 -fastapi-slim==0.111.0 -h11==0.14.0 -httpcore==1.0.4 -httpx==0.27.0 -idna==3.7 -importlib-metadata==6.11.0 -iniconfig==2.0.0 -packaging==24.0 -pluggy==1.5.0 -py-cpuinfo==9.0.0 -pydantic==2.6.2 -pydantic_core==2.16.3 -pytest==7.4.4 -requests==2.32.3 -sniffio==1.3.0 -starlette==0.37.2 -tomli==2.0.1 -typing_extensions==4.9.0 -urllib3==2.2.2 -wrapt==1.16.0 -zipp==3.19.2 --e opentelemetry-instrumentation --e instrumentation/opentelemetry-instrumentation-asgi --e util/opentelemetry-util-http --e instrumentation/opentelemetry-instrumentation-fastapi diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 1c9bd63874..a701dbc5f4 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -84,10 +84,6 @@ "library": "fastapi ~= 0.58", "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", }, - { - "library": "fastapi-slim ~= 0.111", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", - }, { "library": "flask >= 1.0", "instrumentation": "opentelemetry-instrumentation-flask==0.48b0.dev", diff --git a/tox.ini b/tox.ini index 75e8a7f5a0..8552948b6b 100644 --- a/tox.ini +++ b/tox.ini @@ -112,8 +112,8 @@ envlist = lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi - py3{8,9,10,11,12}-test-instrumentation-fastapi-{main,slim} - pypy3-test-instrumentation-fastapi-{main,slim} + py3{8,9,10,11,12}-test-instrumentation-fastapi + pypy3-test-instrumentation-fastapi lint-instrumentation-fastapi ; opentelemetry-instrumentation-flask @@ -556,9 +556,7 @@ commands_pre = fastapi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions fastapi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk fastapi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - fastapi-main: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt - fastapi-slim: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements-slim.txt - lint-instrumentation-fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt + fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt mysql: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api mysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions From f9dc90fedcf2ce9876a497727958878f13642161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:54:15 -0300 Subject: [PATCH 146/335] bump django version in test requirements (#2785) --- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 2ed199fbf3..4f49efb39e 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,7 +1,7 @@ asgiref==3.7.2 backports.zoneinfo==0.2.1 Deprecated==1.2.14 -Django==4.2.14 +Django==4.2.15 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index c3e65be730..9be1266014 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -1,6 +1,6 @@ asgiref==3.7.2 Deprecated==1.2.14 -Django==4.2.14 +Django==4.2.15 importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 From 6981035aecc960310ca131d551597649f233dc2b Mon Sep 17 00:00:00 2001 From: Roberto Villarreal Date: Mon, 12 Aug 2024 10:14:43 -0600 Subject: [PATCH 147/335] Ensure async generators are awaited (#2792) --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/asyncio/__init__.py | 2 +- .../tests/test_asyncio_anext.py | 10 +++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49b66f69df..d4d996caeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2589](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2589)) - `opentelemetry-instrumentation-celery` propagates baggage ([#2385](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2385)) +- `opentelemetry-instrumentation-asyncio` Fixes async generator coroutines not being awaited + ([#2792](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2792)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index f5f0d34c4f..ae10560861 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -262,7 +262,7 @@ def trace_item(self, coro_or_future): async def trace_coroutine(self, coro): if not hasattr(coro, "__name__"): - return coro + return await coro start = default_timer() attr = { "type": "coroutine", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py index e51f059ca0..5241b3f2cc 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -43,19 +43,23 @@ def tearDown(self): # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced. # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute. + # Additionally, ensure the coroutine is actually awaited. @skipIf( sys.version_info < (3, 10), "anext is only available in Python 3.10+" ) def test_asyncio_anext(self): async def main(): async def async_gen(): - for it in range(2): + # nothing special about this range other than to avoid returning a zero + # from a function named 'main' (which might cause confusion about intent) + for it in range(2, 4): yield it async_gen_instance = async_gen() agen = anext(async_gen_instance) - await asyncio.create_task(agen) + return await asyncio.create_task(agen) - asyncio.run(main()) + ret = asyncio.run(main()) + self.assertEqual(ret, 2) # first iteration from range() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) From f1f017fd15489afaa816831b0708c4a13221bb92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:51:34 -0300 Subject: [PATCH 148/335] opentelemetry-bootstrap: remove aws-lambda from default instrumentations (#2786) --- CHANGELOG.md | 5 ++++- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 1 - scripts/generate_instrumentation_bootstrap.py | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4d996caeb..d1a113a91e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation - ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537))) + ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537)) ## Breaking changes +- `opentelemetry-bootstrap` Remove `opentelemetry-instrumentation-aws-lambda` from the defaults instrumentations + ([#2786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2786)) + ## Fixed - `opentelemetry-instrumentation-fastapi` fix `fastapi` auto-instrumentation by removing `fastapi-slim` support, `fastapi-slim` itself is discontinued from maintainers diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index a701dbc5f4..c31863bd31 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -187,7 +187,6 @@ ] default_instrumentations = [ "opentelemetry-instrumentation-asyncio==0.48b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.48b0.dev", "opentelemetry-instrumentation-dbapi==0.48b0.dev", "opentelemetry-instrumentation-logging==0.48b0.dev", "opentelemetry-instrumentation-sqlite3==0.48b0.dev", diff --git a/scripts/generate_instrumentation_bootstrap.py b/scripts/generate_instrumentation_bootstrap.py index 1c0cc30f7b..57af33e303 100755 --- a/scripts/generate_instrumentation_bootstrap.py +++ b/scripts/generate_instrumentation_bootstrap.py @@ -53,12 +53,21 @@ "bootstrap_gen.py", ) +# AWS Lambda instrumentation is excluded from the default list because it often +# requires specific configurations and dependencies that may not be set up +# in all environments. Instead, users who need AWS Lambda support can opt-in +# by manually adding it to their environment. +# See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2787 +packages_to_exclude = ["opentelemetry-instrumentation-aws-lambda"] + def main(): # pylint: disable=no-member default_instrumentations = ast.List(elts=[]) libraries = ast.List(elts=[]) for pkg in get_instrumentation_packages(): + if pkg.get("name") in packages_to_exclude: + continue if not pkg["instruments"]: default_instrumentations.elts.append(ast.Str(pkg["requirement"])) for target_pkg in pkg["instruments"]: From 9c327eae00a17f97c9929bf7edda7eb15247c184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:48:46 -0300 Subject: [PATCH 149/335] bump aiohttp to 3.10.2 (#2796) --- .../test-requirements.txt | 2 +- .../tests/test_aiohttp_client_integration.py | 2 +- .../test-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index fd44fbbc62..be0311238f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.9.4 +aiohttp==3.10.2 aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index adf54c295b..8474bd436f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -468,7 +468,7 @@ async def request_handler(request): [ ( "GET", - (StatusCode.ERROR, "ServerTimeoutError"), + (StatusCode.ERROR, "SocketTimeoutError"), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: f"http://{host}:{port}/test_timeout", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index b83eff27f0..9cd6a3c111 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.9.4 +aiohttp==3.10.2 aiosignal==1.3.1 asgiref==3.7.2 async-timeout==4.0.3 From af9e841742c0f540476cba80d4eeea6673fb9a55 Mon Sep 17 00:00:00 2001 From: shijiadong2022 Date: Thu, 15 Aug 2024 01:26:39 +0800 Subject: [PATCH 150/335] Fix issue opentelemetry-instrumentation-asgi: do not set url.full attribute for server spans (#2735) --- CHANGELOG.md | 2 ++ .../instrumentation/asgi/__init__.py | 10 ++++++---- .../tests/test_asgi_middleware.py | 19 ++++++++----------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1a113a91e..39236a33f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2750](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2750)) - `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics ([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746)) +- `opentelemetry-instrumentation-asgi` do not set `url.full` attribute for server spans + ([#2735](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2735)) - `opentelemetry-instrumentation-grpc` Fixes the issue with the gRPC instrumentation not working with the 1.63.0 and higher version of gRPC ([#2483](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2484)) - `opentelemetry-instrumentation-aws-lambda` Fixing w3c baggage support diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 0525181eac..8e3199cef8 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -354,10 +354,12 @@ def collect_request_attributes( result, path, path, query_string, sem_conv_opt_in_mode ) if http_url: - _set_http_url( - result, remove_url_credentials(http_url), sem_conv_opt_in_mode - ) - + if _report_old(sem_conv_opt_in_mode): + _set_http_url( + result, + remove_url_credentials(http_url), + _HTTPStabilityMode.DEFAULT, + ) http_method = scope.get("method", "") if http_method: _set_http_method( diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index 5bb04adb25..af51faa808 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -58,7 +58,6 @@ SERVER_PORT, ) from opentelemetry.semconv.attributes.url_attributes import ( - URL_FULL, URL_PATH, URL_QUERY, URL_SCHEME, @@ -410,7 +409,6 @@ def validate_outputs( SERVER_ADDRESS: "127.0.0.1", NETWORK_PROTOCOL_VERSION: "1.0", URL_PATH: "/", - URL_FULL: "http://127.0.0.1/", CLIENT_ADDRESS: "127.0.0.1", CLIENT_PORT: 32767, HTTP_RESPONSE_STATUS_CODE: 200, @@ -447,7 +445,6 @@ def validate_outputs( SERVER_ADDRESS: "127.0.0.1", NETWORK_PROTOCOL_VERSION: "1.0", URL_PATH: "/", - URL_FULL: "http://127.0.0.1/", CLIENT_ADDRESS: "127.0.0.1", CLIENT_PORT: 32767, HTTP_RESPONSE_STATUS_CODE: 200, @@ -693,7 +690,6 @@ def update_expected_server(expected): { SERVER_ADDRESS: "0.0.0.0", SERVER_PORT: 80, - URL_FULL: "http://0.0.0.0/", } ) return expected @@ -721,7 +717,6 @@ def update_expected_server(expected): SpanAttributes.HTTP_URL: "http://0.0.0.0/", SERVER_ADDRESS: "0.0.0.0", SERVER_PORT: 80, - URL_FULL: "http://0.0.0.0/", } ) return expected @@ -1009,7 +1004,6 @@ def test_websocket_new_semconv(self): SERVER_ADDRESS: self.scope["server"][0], NETWORK_PROTOCOL_VERSION: self.scope["http_version"], URL_PATH: self.scope["path"], - URL_FULL: f'{self.scope["scheme"]}://{self.scope["server"][0]}{self.scope["path"]}', CLIENT_ADDRESS: self.scope["client"][0], CLIENT_PORT: self.scope["client"][1], HTTP_RESPONSE_STATUS_CODE: 200, @@ -1095,7 +1089,6 @@ def test_websocket_both_semconv(self): SERVER_ADDRESS: self.scope["server"][0], NETWORK_PROTOCOL_VERSION: self.scope["http_version"], URL_PATH: self.scope["path"], - URL_FULL: f'{self.scope["scheme"]}://{self.scope["server"][0]}{self.scope["path"]}', CLIENT_ADDRESS: self.scope["client"][0], CLIENT_PORT: self.scope["client"][1], HTTP_RESPONSE_STATUS_CODE: 200, @@ -1639,7 +1632,6 @@ def test_request_attributes_new_semconv(self): SERVER_ADDRESS: "127.0.0.1", URL_PATH: "/", URL_QUERY: "foo=bar", - URL_FULL: "http://127.0.0.1/?foo=bar", SERVER_PORT: 80, URL_SCHEME: "http", NETWORK_PROTOCOL_VERSION: "1.0", @@ -1676,7 +1668,6 @@ def test_request_attributes_both_semconv(self): SERVER_ADDRESS: "127.0.0.1", URL_PATH: "/", URL_QUERY: "foo=bar", - URL_FULL: "http://127.0.0.1/?foo=bar", SERVER_PORT: 80, URL_SCHEME: "http", NETWORK_PROTOCOL_VERSION: "1.0", @@ -1698,7 +1689,10 @@ def test_query_string_new_semconv(self): self.scope, _HTTPStabilityMode.HTTP, ) - self.assertEqual(attrs[URL_FULL], "http://127.0.0.1/?foo=bar") + self.assertEqual(attrs[URL_SCHEME], "http") + self.assertEqual(attrs[SERVER_ADDRESS], "127.0.0.1") + self.assertEqual(attrs[URL_PATH], "/") + self.assertEqual(attrs[URL_QUERY], "foo=bar") def test_query_string_both_semconv(self): self.scope["query_string"] = b"foo=bar" @@ -1706,10 +1700,13 @@ def test_query_string_both_semconv(self): self.scope, _HTTPStabilityMode.HTTP_DUP, ) - self.assertEqual(attrs[URL_FULL], "http://127.0.0.1/?foo=bar") self.assertEqual( attrs[SpanAttributes.HTTP_URL], "http://127.0.0.1/?foo=bar" ) + self.assertEqual(attrs[URL_SCHEME], "http") + self.assertEqual(attrs[SERVER_ADDRESS], "127.0.0.1") + self.assertEqual(attrs[URL_PATH], "/") + self.assertEqual(attrs[URL_QUERY], "foo=bar") def test_query_string_percent_bytes(self): self.scope["query_string"] = b"foo%3Dbar" From e7f647e91b95ae651e97032c9bc5c8f0ff549d2d Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 15 Aug 2024 17:05:45 -0600 Subject: [PATCH 151/335] Add skip clause for Public API check (#2801) Fixes #2800 --- .../src/generate_workflows_lib/misc.yml.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index fe479ae5b2..807da0eb1a 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -25,6 +25,11 @@ jobs: !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') && github.actor != 'opentelemetrybot' {%- endif %} + {%- if job_data == "public-symbols-check" %} + if: | + !contains(github.event.pull_request.labels.*.name, 'Approve Public API check') + && github.actor != 'opentelemetrybot' + {%- endif %} steps: - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} uses: actions/checkout@v4 From 4108d57e7ae6bb38d1ac638a6392f3a53dac2853 Mon Sep 17 00:00:00 2001 From: B Ramshankar Date: Fri, 16 Aug 2024 22:27:24 +0100 Subject: [PATCH 152/335] fix for Audit and test opentelemetry-instrumentation-jinja2 #978 (#2799) --- .../tests/test_jinja2.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py b/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py index 542a65d220..26ba98e69b 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py @@ -219,3 +219,14 @@ def test_uninstrumented(self): self.assertEqual(len(spans), 0) Jinja2Instrumentor().instrument() + + def test_no_op_tracer_provider(self): + self.memory_exporter.clear() + Jinja2Instrumentor().uninstrument() + Jinja2Instrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + template = jinja2.environment.Template("Hello {{name}}!") + self.assertEqual(template.render(name="Jinja"), "Hello Jinja!") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) From 560fd04962f11c2cfa68407c88c51442bc864fa6 Mon Sep 17 00:00:00 2001 From: Jordan Gibbings Date: Mon, 19 Aug 2024 22:59:24 +0800 Subject: [PATCH 153/335] fix(tornado): ensure reading future.result() won't throw an exception in client.py _finish_tracing_callback (#2563) --- CHANGELOG.md | 2 + .../instrumentation/tornado/client.py | 56 ++++++++++++------- .../tests/test_instrumentation.py | 47 +++++++++++++++- 3 files changed, 83 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39236a33f3..8c31e01235 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2385](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2385)) - `opentelemetry-instrumentation-asyncio` Fixes async generator coroutines not being awaited ([#2792](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2792)) +- `opentelemetry-instrumentation-tornado` Handle http client exception and record exception info into span + ([#2563](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2563)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py index 090f87a88b..fa0e53bf95 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py @@ -21,7 +21,7 @@ from opentelemetry.instrumentation.utils import http_status_to_status_code from opentelemetry.propagate import inject from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace.status import Status +from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import remove_url_credentials @@ -105,37 +105,53 @@ def _finish_tracing_callback( request_size_histogram, response_size_histogram, ): + response = None status_code = None + status = None description = None - exc = future.exception() - - response = future.result() - if span.is_recording() and exc: + exc = future.exception() + if exc: + description = f"{type(exc).__qualname__}: {exc}" if isinstance(exc, HTTPError): + response = exc.response status_code = exc.code - description = f"{type(exc).__name__}: {exc}" + status = Status( + status_code=http_status_to_status_code(status_code), + description=description, + ) + else: + status = Status( + status_code=StatusCode.ERROR, + description=description, + ) + span.record_exception(exc) else: + response = future.result() status_code = response.code + status = Status( + status_code=http_status_to_status_code(status_code), + description=description, + ) if status_code is not None: span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) - span.set_status( - Status( - status_code=http_status_to_status_code(status_code), - description=description, - ) - ) + span.set_status(status) - metric_attributes = _create_metric_attributes(response) - request_size = int(response.request.headers.get("Content-Length", 0)) - response_size = int(response.headers.get("Content-Length", 0)) + if response is not None: + metric_attributes = _create_metric_attributes(response) + request_size = int(response.request.headers.get("Content-Length", 0)) + response_size = int(response.headers.get("Content-Length", 0)) - duration_histogram.record( - response.request_time, attributes=metric_attributes - ) - request_size_histogram.record(request_size, attributes=metric_attributes) - response_size_histogram.record(response_size, attributes=metric_attributes) + duration_histogram.record( + response.request_time, attributes=metric_attributes + ) + request_size_histogram.record( + request_size, attributes=metric_attributes + ) + response_size_histogram.record( + response_size, attributes=metric_attributes + ) if response_hook: response_hook(span, future) diff --git a/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py index 01cdddceed..daf2ddd846 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py @@ -16,6 +16,7 @@ from unittest.mock import Mock, patch from http_server_mock import HttpServerMock +from tornado.httpclient import HTTPClientError from tornado.testing import AsyncHTTPTestCase from opentelemetry import trace @@ -32,7 +33,7 @@ from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase -from opentelemetry.trace import SpanKind +from opentelemetry.trace import SpanKind, StatusCode from opentelemetry.util.http import ( OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, @@ -493,7 +494,6 @@ def test_response_headers(self): self.assertEqual(len(spans), 3) self.assertTraceResponseHeaderMatchesSpan(response.headers, spans[1]) - self.memory_exporter.clear() set_global_response_propagator(orig) def test_credential_removal(self): @@ -602,6 +602,49 @@ def client_response_hook(span, response): self.memory_exporter.clear() +class TestTornadoHTTPClientInstrumentation(TornadoTest, WsgiTestBase): + def test_http_client_success_response(self): + response = self.fetch("/") + self.assertEqual(response.code, 201) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 3) + manual, server, client = self.sorted_spans(spans) + self.assertEqual(manual.name, "manual") + self.assertEqual(server.name, "GET /") + self.assertEqual(client.name, "GET") + self.assertEqual(client.status.status_code, StatusCode.UNSET) + self.memory_exporter.clear() + + def test_http_client_failed_response(self): + # when an exception isn't thrown + response = self.fetch("/some-404") + self.assertEqual(response.code, 404) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + server, client = self.sorted_spans(spans) + self.assertEqual(server.name, "GET /some-404") + self.assertEqual(client.name, "GET") + self.assertEqual(client.status.status_code, StatusCode.ERROR) + self.memory_exporter.clear() + + # when an exception is thrown + try: + response = self.fetch("/some-404", raise_error=True) + self.assertEqual(response.code, 404) + except HTTPClientError: + pass # expected exception - continue + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + server, client = self.sorted_spans(spans) + self.assertEqual(server.name, "GET /some-404") + self.assertEqual(client.name, "GET") + self.assertEqual(client.status.status_code, StatusCode.ERROR) + self.memory_exporter.clear() + + class TestTornadoUninstrument(TornadoTest): def test_uninstrument(self): response = self.fetch("/") From dda369b7247919b8d4351b6a2535c7ad9e7f0fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 19 Aug 2024 12:39:17 -0300 Subject: [PATCH 154/335] bump webob to 1.8.8 in test requirements (#2804) --- .../opentelemetry-instrumentation-pyramid/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 56f89f8e8e..aa387f8177 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -15,7 +15,7 @@ tomli==2.0.1 translationstring==1.4 typing_extensions==4.9.0 venusian==3.1.0 -WebOb==1.8.7 +WebOb==1.8.8 Werkzeug==3.0.3 wrapt==1.16.0 zipp==3.19.2 From 1ad9d9030880d260df3b52c2e2c334b07f1bde4a Mon Sep 17 00:00:00 2001 From: Mrugesh Master Date: Wed, 21 Aug 2024 15:24:46 -0700 Subject: [PATCH 155/335] Divided proc_cpu_percent by 100 to get value between 0 and 1 (#2812) --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/system_metrics/__init__.py | 2 +- .../tests/test_system_metrics.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c31e01235..5abca8227a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Fixed +- `opentelemetry-instrumentation-system-metrics` fix `process.runtime.cpu.utilization` values to be shown in range of 0 to 1 + ([2812](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2812)) - `opentelemetry-instrumentation-fastapi` fix `fastapi` auto-instrumentation by removing `fastapi-slim` support, `fastapi-slim` itself is discontinued from maintainers ([2783](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2783)) - `opentelemetry-instrumentation-aws-lambda` Avoid exception when a handler is not present. diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index b7ffb25431..1b9a36c4cb 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -729,7 +729,7 @@ def _get_runtime_cpu_utilization( """Observer callback for runtime CPU utilization""" proc_cpu_percent = self._proc.cpu_percent() yield Observation( - proc_cpu_percent, + proc_cpu_percent / 100, self._runtime_cpu_utilization_labels.copy(), ) diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py index 1d6f08892e..bf3a5c6ee2 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py @@ -839,7 +839,7 @@ def test_runtime_thread_num(self, mock_process_thread_num): def test_runtime_cpu_percent(self, mock_process_cpu_percent): mock_process_cpu_percent.configure_mock(**{"return_value": 42}) - expected = [_SystemMetricsResult({}, 42)] + expected = [_SystemMetricsResult({}, 0.42)] self._test_metrics( f"process.runtime.{self.implementation}.cpu.utilization", expected ) From fb75ac05d8dfffdd71c89a9af8eadd4a08da9f21 Mon Sep 17 00:00:00 2001 From: Ben C <108300492+benbo34@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:15:29 -0400 Subject: [PATCH 156/335] replaced broken link (#2815) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 990d6b14a2..d01d43181f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ and [**Maintainer**](https://github.com/open-telemetry/community/blob/main/commu Before you can contribute, you will need to sign the [Contributor License Agreement](https://docs.linuxfoundation.org/lfx/easycla/contributors). -Please also read the [OpenTelemetry Contributor Guide](https://github.com/open-telemetry/community/blob/main/CONTRIBUTING.md). +Please also read the [OpenTelemetry Contributor Guide](https://github.com/open-telemetry/community/blob/main/guides/contributor/README.md). ## Index From bc4d2c5b75e3e523c4be2da2fa01f2c02e4f9453 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Fri, 23 Aug 2024 16:56:36 -0700 Subject: [PATCH 157/335] Fix `http.host` and `net.peer.ip` new http semconv mapping (#2814) --- CHANGELOG.md | 2 + .../instrumentation/asgi/__init__.py | 10 ++-- .../tests/test_asgi_middleware.py | 19 ++----- .../instrumentation/httpx/__init__.py | 4 +- .../instrumentation/requests/__init__.py | 6 +- .../instrumentation/urllib3/__init__.py | 6 +- .../instrumentation/wsgi/__init__.py | 4 +- .../opentelemetry/instrumentation/_semconv.py | 56 ++++++++++++------- 8 files changed, 59 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5abca8227a..c5ce56423a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2792](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2792)) - `opentelemetry-instrumentation-tornado` Handle http client exception and record exception info into span ([#2563](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2563)) +- `opentelemetry-instrumentation` fix `http.host` new http semantic convention mapping to depend on `kind` of span + ([#2814](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2814)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 8e3199cef8..295eb2a043 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -215,10 +215,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A _server_duration_attrs_new, _server_duration_attrs_old, _set_http_flavor_version, - _set_http_host, + _set_http_host_server, _set_http_method, _set_http_net_host_port, - _set_http_peer_ip, + _set_http_peer_ip_server, _set_http_peer_port_server, _set_http_scheme, _set_http_target, @@ -342,7 +342,7 @@ def collect_request_attributes( if scheme: _set_http_scheme(result, scheme, sem_conv_opt_in_mode) if server_host: - _set_http_host(result, server_host, sem_conv_opt_in_mode) + _set_http_host_server(result, server_host, sem_conv_opt_in_mode) if port: _set_http_net_host_port(result, port, sem_conv_opt_in_mode) flavor = scope.get("http_version") @@ -380,7 +380,9 @@ def collect_request_attributes( _set_http_user_agent(result, http_user_agent[0], sem_conv_opt_in_mode) if "client" in scope and scope["client"] is not None: - _set_http_peer_ip(result, scope.get("client")[0], sem_conv_opt_in_mode) + _set_http_peer_ip_server( + result, scope.get("client")[0], sem_conv_opt_in_mode + ) _set_http_peer_port_server( result, scope.get("client")[1], sem_conv_opt_in_mode ) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index af51faa808..d89f4a54e0 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -53,10 +53,7 @@ from opentelemetry.semconv.attributes.network_attributes import ( NETWORK_PROTOCOL_VERSION, ) -from opentelemetry.semconv.attributes.server_attributes import ( - SERVER_ADDRESS, - SERVER_PORT, -) +from opentelemetry.semconv.attributes.server_attributes import SERVER_PORT from opentelemetry.semconv.attributes.url_attributes import ( URL_PATH, URL_QUERY, @@ -406,7 +403,6 @@ def validate_outputs( HTTP_REQUEST_METHOD: "GET", URL_SCHEME: "http", SERVER_PORT: 80, - SERVER_ADDRESS: "127.0.0.1", NETWORK_PROTOCOL_VERSION: "1.0", URL_PATH: "/", CLIENT_ADDRESS: "127.0.0.1", @@ -442,7 +438,6 @@ def validate_outputs( HTTP_REQUEST_METHOD: "GET", URL_SCHEME: "http", SERVER_PORT: 80, - SERVER_ADDRESS: "127.0.0.1", NETWORK_PROTOCOL_VERSION: "1.0", URL_PATH: "/", CLIENT_ADDRESS: "127.0.0.1", @@ -688,7 +683,7 @@ def test_behavior_with_scope_server_as_none_new_semconv(self): def update_expected_server(expected): expected[3]["attributes"].update( { - SERVER_ADDRESS: "0.0.0.0", + CLIENT_ADDRESS: "0.0.0.0", SERVER_PORT: 80, } ) @@ -715,7 +710,7 @@ def update_expected_server(expected): SpanAttributes.HTTP_HOST: "0.0.0.0", SpanAttributes.NET_HOST_PORT: 80, SpanAttributes.HTTP_URL: "http://0.0.0.0/", - SERVER_ADDRESS: "0.0.0.0", + CLIENT_ADDRESS: "0.0.0.0", SERVER_PORT: 80, } ) @@ -1001,7 +996,6 @@ def test_websocket_new_semconv(self): "attributes": { URL_SCHEME: self.scope["scheme"], SERVER_PORT: self.scope["server"][1], - SERVER_ADDRESS: self.scope["server"][0], NETWORK_PROTOCOL_VERSION: self.scope["http_version"], URL_PATH: self.scope["path"], CLIENT_ADDRESS: self.scope["client"][0], @@ -1086,7 +1080,6 @@ def test_websocket_both_semconv(self): SpanAttributes.HTTP_METHOD: self.scope["method"], URL_SCHEME: self.scope["scheme"], SERVER_PORT: self.scope["server"][1], - SERVER_ADDRESS: self.scope["server"][0], NETWORK_PROTOCOL_VERSION: self.scope["http_version"], URL_PATH: self.scope["path"], CLIENT_ADDRESS: self.scope["client"][0], @@ -1629,7 +1622,6 @@ def test_request_attributes_new_semconv(self): attrs, { HTTP_REQUEST_METHOD: "GET", - SERVER_ADDRESS: "127.0.0.1", URL_PATH: "/", URL_QUERY: "foo=bar", SERVER_PORT: 80, @@ -1665,7 +1657,6 @@ def test_request_attributes_both_semconv(self): SpanAttributes.NET_PEER_IP: "127.0.0.1", SpanAttributes.NET_PEER_PORT: 32767, HTTP_REQUEST_METHOD: "GET", - SERVER_ADDRESS: "127.0.0.1", URL_PATH: "/", URL_QUERY: "foo=bar", SERVER_PORT: 80, @@ -1690,7 +1681,7 @@ def test_query_string_new_semconv(self): _HTTPStabilityMode.HTTP, ) self.assertEqual(attrs[URL_SCHEME], "http") - self.assertEqual(attrs[SERVER_ADDRESS], "127.0.0.1") + self.assertEqual(attrs[CLIENT_ADDRESS], "127.0.0.1") self.assertEqual(attrs[URL_PATH], "/") self.assertEqual(attrs[URL_QUERY], "foo=bar") @@ -1704,7 +1695,7 @@ def test_query_string_both_semconv(self): attrs[SpanAttributes.HTTP_URL], "http://127.0.0.1/?foo=bar" ) self.assertEqual(attrs[URL_SCHEME], "http") - self.assertEqual(attrs[SERVER_ADDRESS], "127.0.0.1") + self.assertEqual(attrs[CLIENT_ADDRESS], "127.0.0.1") self.assertEqual(attrs[URL_PATH], "/") self.assertEqual(attrs[URL_QUERY], "foo=bar") diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index f2a18a2770..43db6c3a82 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -202,7 +202,7 @@ async def async_response_hook(span, request, response): _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, - _set_http_host, + _set_http_host_client, _set_http_method, _set_http_network_protocol_version, _set_http_peer_port_client, @@ -342,7 +342,7 @@ def _apply_request_client_attributes_to_span( if _report_new(semconv): if url.host: # http semconv transition: http.host -> server.address - _set_http_host(span_attributes, url.host, semconv) + _set_http_host_client(span_attributes, url.host, semconv) # http semconv transition: net.sock.peer.addr -> network.peer.address span_attributes[NETWORK_PEER_ADDRESS] = url.host if url.port: diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 3aa1b476f5..db67d378d9 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -92,7 +92,7 @@ def response_hook(span, request_obj, response) _OpenTelemetryStabilitySignalType, _report_new, _report_old, - _set_http_host, + _set_http_host_client, _set_http_method, _set_http_net_peer_name_client, _set_http_network_protocol_version, @@ -212,14 +212,14 @@ def get_or_create_headers(): metric_labels, parsed_url.scheme, sem_conv_opt_in_mode ) if parsed_url.hostname: - _set_http_host( + _set_http_host_client( metric_labels, parsed_url.hostname, sem_conv_opt_in_mode ) _set_http_net_peer_name_client( metric_labels, parsed_url.hostname, sem_conv_opt_in_mode ) if _report_new(sem_conv_opt_in_mode): - _set_http_host( + _set_http_host_client( span_attributes, parsed_url.hostname, sem_conv_opt_in_mode, diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index 4bcd0816fd..1c83f3f447 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -103,7 +103,7 @@ def response_hook( _OpenTelemetryStabilitySignalType, _report_new, _report_old, - _set_http_host, + _set_http_host_client, _set_http_method, _set_http_net_peer_name_client, _set_http_network_protocol_version, @@ -491,7 +491,9 @@ def _set_metric_attributes( sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ) -> None: - _set_http_host(metric_attributes, instance.host, sem_conv_opt_in_mode) + _set_http_host_client( + metric_attributes, instance.host, sem_conv_opt_in_mode + ) _set_http_scheme(metric_attributes, instance.scheme, sem_conv_opt_in_mode) _set_http_method( metric_attributes, diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 355b1d7458..88704f35ab 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -231,7 +231,7 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he _set_http_net_host, _set_http_net_host_port, _set_http_net_peer_name_server, - _set_http_peer_ip, + _set_http_peer_ip_server, _set_http_peer_port_server, _set_http_scheme, _set_http_target, @@ -360,7 +360,7 @@ def collect_request_attributes( remote_addr = environ.get("REMOTE_ADDR") if remote_addr: - _set_http_peer_ip(result, remote_addr, sem_conv_opt_in_mode) + _set_http_peer_ip_server(result, remote_addr, sem_conv_opt_in_mode) peer_port = environ.get("REMOTE_PORT") if peer_port: diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 33668333ce..c4e720fd04 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -252,16 +252,32 @@ def _set_http_scheme(result, scheme, sem_conv_opt_in_mode): set_string_attribute(result, URL_SCHEME, scheme) -def _set_http_host(result, host, sem_conv_opt_in_mode): +def _set_http_flavor_version(result, version, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.HTTP_HOST, host) + set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SERVER_ADDRESS, host) + set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) + + +def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode): + if _report_old(sem_conv_opt_in_mode): + set_string_attribute( + result, SpanAttributes.HTTP_USER_AGENT, user_agent + ) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent) # Client +def _set_http_host_client(result, host, sem_conv_opt_in_mode): + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, SpanAttributes.HTTP_HOST, host) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, SERVER_ADDRESS, host) + + def _set_http_net_peer_name_client(result, peer_name, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): set_string_attribute(result, SpanAttributes.NET_PEER_NAME, peer_name) @@ -310,27 +326,32 @@ def _set_http_target(result, target, path, query, sem_conv_opt_in_mode): set_string_attribute(result, URL_QUERY, query) -def _set_http_peer_ip(result, ip, sem_conv_opt_in_mode): +def _set_http_host_server(result, host, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.NET_PEER_IP, ip) + set_string_attribute(result, SpanAttributes.HTTP_HOST, host) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, CLIENT_ADDRESS, ip) + set_string_attribute(result, CLIENT_ADDRESS, host) -def _set_http_peer_port_server(result, port, sem_conv_opt_in_mode): +# net.peer.ip -> net.sock.peer.addr +# https://github.com/open-telemetry/semantic-conventions/blob/40db676ca0e735aa84f242b5a0fb14e49438b69b/schemas/1.15.0#L18 +# net.sock.peer.addr -> client.socket.address for server spans (TODO) AND client.address if missing +# https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/CHANGELOG.md#v1210-2023-07-13 +# https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#common-attributes-across-http-client-and-server-spans +def _set_http_peer_ip_server(result, ip, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): - set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port) + set_string_attribute(result, SpanAttributes.NET_PEER_IP, ip) if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, CLIENT_PORT, port) + # Only populate if not already populated + if not result.get(CLIENT_ADDRESS): + set_string_attribute(result, CLIENT_ADDRESS, ip) -def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode): +def _set_http_peer_port_server(result, port, sem_conv_opt_in_mode): if _report_old(sem_conv_opt_in_mode): - set_string_attribute( - result, SpanAttributes.HTTP_USER_AGENT, user_agent - ) + set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port) if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent) + set_int_attribute(result, CLIENT_PORT, port) def _set_http_net_peer_name_server(result, name, sem_conv_opt_in_mode): @@ -340,13 +361,6 @@ def _set_http_net_peer_name_server(result, name, sem_conv_opt_in_mode): set_string_attribute(result, CLIENT_ADDRESS, name) -def _set_http_flavor_version(result, version, sem_conv_opt_in_mode): - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) - - def _set_status( span, metrics_attributes: dict, From 19f8e775ce76841d097b11ec42c886e5ed46ea06 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 26 Aug 2024 18:38:07 +0200 Subject: [PATCH 158/335] Prepare asgi tests to support newer asgiref version (#2778) --- .../tests/test_asgi_custom_headers.py | 98 ++++--- .../tests/test_asgi_middleware.py | 260 +++++++++--------- 2 files changed, 195 insertions(+), 163 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py index 5394d62ff0..f6cb05fbda 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py @@ -1,7 +1,21 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import os import opentelemetry.instrumentation.asgi as otel_asgi -from opentelemetry.test.asgitestutil import AsgiTestBase +from opentelemetry.test.asgitestutil import AsyncAsgiTestBase from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind from opentelemetry.util.http import ( @@ -90,7 +104,7 @@ async def websocket_app_with_custom_headers(scope, receive, send): break -class TestCustomHeaders(AsgiTestBase, TestBase): +class TestCustomHeaders(AsyncAsgiTestBase): constructor_params = {} __test__ = False @@ -108,7 +122,7 @@ def setUp(self): **self.constructor_params, ) - def test_http_custom_request_headers_in_span_attributes(self): + async def test_http_custom_request_headers_in_span_attributes(self): self.scope["headers"].extend( [ (b"custom-test-header-1", b"test-header-value-1"), @@ -119,8 +133,8 @@ def test_http_custom_request_headers_in_span_attributes(self): ] ) self.seed_app(self.app) - self.send_default_request() - self.get_all_output() + await self.send_default_request() + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.request.header.custom_test_header_1": ( @@ -139,7 +153,7 @@ def test_http_custom_request_headers_in_span_attributes(self): if span.kind == SpanKind.SERVER: self.assertSpanHasAttributes(span, expected) - def test_http_repeat_request_headers_in_span_attributes(self): + async def test_http_repeat_request_headers_in_span_attributes(self): self.scope["headers"].extend( [ (b"custom-test-header-1", b"test-header-value-1"), @@ -147,8 +161,8 @@ def test_http_repeat_request_headers_in_span_attributes(self): ] ) self.seed_app(self.app) - self.send_default_request() - self.get_all_output() + await self.send_default_request() + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.request.header.custom_test_header_1": ( @@ -159,15 +173,15 @@ def test_http_repeat_request_headers_in_span_attributes(self): span = next(span for span in span_list if span.kind == SpanKind.SERVER) self.assertSpanHasAttributes(span, expected) - def test_http_custom_request_headers_not_in_span_attributes(self): + async def test_http_custom_request_headers_not_in_span_attributes(self): self.scope["headers"].extend( [ (b"custom-test-header-1", b"test-header-value-1"), ] ) self.seed_app(self.app) - self.send_default_request() - self.get_all_output() + await self.send_default_request() + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.request.header.custom_test_header_1": ( @@ -185,15 +199,15 @@ def test_http_custom_request_headers_not_in_span_attributes(self): for key, _ in not_expected.items(): self.assertNotIn(key, span.attributes) - def test_http_custom_response_headers_in_span_attributes(self): + async def test_http_custom_response_headers_in_span_attributes(self): self.app = otel_asgi.OpenTelemetryMiddleware( http_app_with_custom_headers, tracer_provider=self.tracer_provider, **self.constructor_params, ) self.seed_app(self.app) - self.send_default_request() - self.get_all_output() + await self.send_default_request() + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.response.header.custom_test_header_1": ( @@ -214,15 +228,15 @@ def test_http_custom_response_headers_in_span_attributes(self): if span.kind == SpanKind.SERVER: self.assertSpanHasAttributes(span, expected) - def test_http_repeat_response_headers_in_span_attributes(self): + async def test_http_repeat_response_headers_in_span_attributes(self): self.app = otel_asgi.OpenTelemetryMiddleware( http_app_with_repeat_headers, tracer_provider=self.tracer_provider, **self.constructor_params, ) self.seed_app(self.app) - self.send_default_request() - self.get_all_output() + await self.send_default_request() + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.response.header.custom_test_header_1": ( @@ -233,15 +247,15 @@ def test_http_repeat_response_headers_in_span_attributes(self): span = next(span for span in span_list if span.kind == SpanKind.SERVER) self.assertSpanHasAttributes(span, expected) - def test_http_custom_response_headers_not_in_span_attributes(self): + async def test_http_custom_response_headers_not_in_span_attributes(self): self.app = otel_asgi.OpenTelemetryMiddleware( http_app_with_custom_headers, tracer_provider=self.tracer_provider, **self.constructor_params, ) self.seed_app(self.app) - self.send_default_request() - self.get_all_output() + await self.send_default_request() + await self.get_all_output() span_list = self.exporter.get_finished_spans() not_expected = { "http.response.header.custom_test_header_3": ( @@ -253,7 +267,7 @@ def test_http_custom_response_headers_not_in_span_attributes(self): for key, _ in not_expected.items(): self.assertNotIn(key, span.attributes) - def test_websocket_custom_request_headers_in_span_attributes(self): + async def test_websocket_custom_request_headers_in_span_attributes(self): self.scope = { "type": "websocket", "http_version": "1.1", @@ -271,11 +285,11 @@ def test_websocket_custom_request_headers_in_span_attributes(self): "server": ("127.0.0.1", 80), } self.seed_app(self.app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.request.header.custom_test_header_1": ( @@ -294,7 +308,9 @@ def test_websocket_custom_request_headers_in_span_attributes(self): if span.kind == SpanKind.SERVER: self.assertSpanHasAttributes(span, expected) - def test_websocket_custom_request_headers_not_in_span_attributes(self): + async def test_websocket_custom_request_headers_not_in_span_attributes( + self, + ): self.scope = { "type": "websocket", "http_version": "1.1", @@ -309,11 +325,11 @@ def test_websocket_custom_request_headers_not_in_span_attributes(self): "server": ("127.0.0.1", 80), } self.seed_app(self.app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.get_all_output() span_list = self.exporter.get_finished_spans() not_expected = { "http.request.header.custom_test_header_3": ( @@ -325,7 +341,7 @@ def test_websocket_custom_request_headers_not_in_span_attributes(self): for key, _ in not_expected.items(): self.assertNotIn(key, span.attributes) - def test_websocket_custom_response_headers_in_span_attributes(self): + async def test_websocket_custom_response_headers_in_span_attributes(self): self.scope = { "type": "websocket", "http_version": "1.1", @@ -342,10 +358,10 @@ def test_websocket_custom_response_headers_in_span_attributes(self): **self.constructor_params, ) self.seed_app(self.app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + await self.get_all_output() span_list = self.exporter.get_finished_spans() expected = { "http.response.header.custom_test_header_1": ( @@ -366,7 +382,9 @@ def test_websocket_custom_response_headers_in_span_attributes(self): if span.kind == SpanKind.SERVER: self.assertSpanHasAttributes(span, expected) - def test_websocket_custom_response_headers_not_in_span_attributes(self): + async def test_websocket_custom_response_headers_not_in_span_attributes( + self, + ): self.scope = { "type": "websocket", "http_version": "1.1", @@ -383,10 +401,10 @@ def test_websocket_custom_response_headers_not_in_span_attributes(self): **self.constructor_params, ) self.seed_app(self.app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + await self.get_all_output() span_list = self.exporter.get_finished_spans() not_expected = { "http.response.header.custom_test_header_3": ( diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index d89f4a54e0..a21dd626c8 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -14,7 +14,6 @@ # pylint: disable=too-many-lines -import asyncio import sys import time import unittest @@ -64,7 +63,7 @@ ) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.asgitestutil import ( - AsgiTestBase, + AsyncAsgiTestBase, setup_testing_defaults, ) from opentelemetry.test.test_base import TestBase @@ -275,7 +274,7 @@ async def error_asgi(scope, receive, send): # pylint: disable=too-many-public-methods -class TestAsgiApplication(AsgiTestBase): +class TestAsgiApplication(AsyncAsgiTestBase): def setUp(self): super().setUp() @@ -477,31 +476,31 @@ def validate_outputs( "opentelemetry.instrumentation.asgi", ) - def test_basic_asgi_call(self): + async def test_basic_asgi_call(self): """Test that spans are emitted as expected.""" app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs) - def test_basic_asgi_call_new_semconv(self): + async def test_basic_asgi_call_new_semconv(self): """Test that spans are emitted as expected.""" app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, old_sem_conv=False, new_sem_conv=True) - def test_basic_asgi_call_both_semconv(self): + async def test_basic_asgi_call_both_semconv(self): """Test that spans are emitted as expected.""" app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, old_sem_conv=True, new_sem_conv=True) - def test_asgi_not_recording(self): + async def test_asgi_not_recording(self): mock_tracer = mock.Mock() mock_span = mock.Mock() mock_span.is_recording.return_value = False @@ -514,21 +513,21 @@ def test_asgi_not_recording(self): tracer.return_value = mock_tracer app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() self.assertFalse(mock_span.is_recording()) self.assertTrue(mock_span.is_recording.called) self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) - def test_asgi_exc_info(self): + async def test_asgi_exc_info(self): """Test that exception information is emitted as expected.""" app = otel_asgi.OpenTelemetryMiddleware(error_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, error=ValueError) - def test_long_response(self): + async def test_long_response(self): """Test that the server span is ended on the final response body message. If the server span is ended early then this test will fail due @@ -536,8 +535,8 @@ def test_long_response(self): """ app = otel_asgi.OpenTelemetryMiddleware(long_response_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() def add_more_body_spans(expected: list): more_body_span = { @@ -551,12 +550,12 @@ def add_more_body_spans(expected: list): self.validate_outputs(outputs, modifiers=[add_more_body_spans]) - def test_background_execution(self): + async def test_background_execution(self): """Test that the server span is ended BEFORE the background task is finished.""" app = otel_asgi.OpenTelemetryMiddleware(background_execution_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs) span_list = self.memory_exporter.get_finished_spans() server_span = span_list[-1] @@ -567,15 +566,15 @@ def test_background_execution(self): _SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9, ) - def test_trailers(self): + async def test_trailers(self): """Test that trailers are emitted as expected and that the server span is ended BEFORE the background task is finished.""" app = otel_asgi.OpenTelemetryMiddleware( background_execution_trailers_asgi ) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() def add_body_and_trailer_span(expected: list): body_span = { @@ -602,7 +601,7 @@ def add_body_and_trailer_span(expected: list): _SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9, ) - def test_override_span_name(self): + async def test_override_span_name(self): """Test that default span_names can be overwritten by our callback function.""" span_name = "Dymaxion" @@ -623,11 +622,11 @@ def update_expected_span_name(expected): simple_asgi, default_span_details=get_predefined_span_details ) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_span_name]) - def test_custom_tracer_provider_otel_asgi(self): + async def test_custom_tracer_provider_otel_asgi(self): resource = resources.Resource.create({"service-test-key": "value"}) result = TestBase.create_tracer_provider(resource=resource) tracer_provider, exporter = result @@ -636,28 +635,28 @@ def test_custom_tracer_provider_otel_asgi(self): simple_asgi, tracer_provider=tracer_provider ) self.seed_app(app) - self.send_default_request() + await self.send_default_request() span_list = exporter.get_finished_spans() for span in span_list: self.assertEqual( span.resource.attributes["service-test-key"], "value" ) - def test_no_op_tracer_provider_otel_asgi(self): + async def test_no_op_tracer_provider_otel_asgi(self): app = otel_asgi.OpenTelemetryMiddleware( simple_asgi, tracer_provider=trace_api.NoOpTracerProvider() ) self.seed_app(app) - self.send_default_request() + await self.send_default_request() - response_start, response_body, *_ = self.get_all_output() + response_start, response_body, *_ = await self.get_all_output() self.assertEqual(response_body["body"], b"*") self.assertEqual(response_start["status"], 200) span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 0) - def test_behavior_with_scope_server_as_none(self): + async def test_behavior_with_scope_server_as_none(self): """Test that middleware is ok when server is none in scope.""" def update_expected_server(expected): @@ -673,11 +672,11 @@ def update_expected_server(expected): self.scope["server"] = None app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_server]) - def test_behavior_with_scope_server_as_none_new_semconv(self): + async def test_behavior_with_scope_server_as_none_new_semconv(self): """Test that middleware is ok when server is none in scope.""" def update_expected_server(expected): @@ -692,8 +691,8 @@ def update_expected_server(expected): self.scope["server"] = None app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs( outputs, modifiers=[update_expected_server], @@ -701,7 +700,7 @@ def update_expected_server(expected): new_sem_conv=True, ) - def test_behavior_with_scope_server_as_none_both_semconv(self): + async def test_behavior_with_scope_server_as_none_both_semconv(self): """Test that middleware is ok when server is none in scope.""" def update_expected_server(expected): @@ -719,8 +718,8 @@ def update_expected_server(expected): self.scope["server"] = None app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs( outputs, modifiers=[update_expected_server], @@ -728,7 +727,7 @@ def update_expected_server(expected): new_sem_conv=True, ) - def test_host_header(self): + async def test_host_header(self): """Test that host header is converted to http.server_name.""" hostname = b"server_name_1" @@ -741,11 +740,11 @@ def update_expected_server(expected): self.scope["headers"].append([b"host", hostname]) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_server]) - def test_host_header_both_semconv(self): + async def test_host_header_both_semconv(self): """Test that host header is converted to http.server_name.""" hostname = b"server_name_1" @@ -758,8 +757,8 @@ def update_expected_server(expected): self.scope["headers"].append([b"host", hostname]) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs( outputs, modifiers=[update_expected_server], @@ -767,7 +766,7 @@ def update_expected_server(expected): new_sem_conv=True, ) - def test_user_agent(self): + async def test_user_agent(self): """Test that host header is converted to http.server_name.""" user_agent = b"test-agent" @@ -780,11 +779,11 @@ def update_expected_user_agent(expected): self.scope["headers"].append([b"user-agent", user_agent]) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs(outputs, modifiers=[update_expected_user_agent]) - def test_user_agent_new_semconv(self): + async def test_user_agent_new_semconv(self): """Test that host header is converted to http.server_name.""" user_agent = b"test-agent" @@ -797,8 +796,8 @@ def update_expected_user_agent(expected): self.scope["headers"].append([b"user-agent", user_agent]) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs( outputs, modifiers=[update_expected_user_agent], @@ -806,7 +805,7 @@ def update_expected_user_agent(expected): new_sem_conv=True, ) - def test_user_agent_both_semconv(self): + async def test_user_agent_both_semconv(self): """Test that host header is converted to http.server_name.""" user_agent = b"test-agent" @@ -822,8 +821,8 @@ def update_expected_user_agent(expected): self.scope["headers"].append([b"user-agent", user_agent]) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs( outputs, modifiers=[update_expected_user_agent], @@ -831,7 +830,7 @@ def update_expected_user_agent(expected): new_sem_conv=True, ) - def test_traceresponse_header(self): + async def test_traceresponse_header(self): """Test a traceresponse header is sent when a global propagator is set.""" orig = get_global_response_propagator() @@ -839,12 +838,12 @@ def test_traceresponse_header(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() + response_start, response_body, *_ = await self.get_all_output() span = self.memory_exporter.get_finished_spans()[-1] self.assertEqual(trace_api.SpanKind.SERVER, span.kind) - response_start, response_body, *_ = self.get_all_output() self.assertEqual(response_body["body"], b"*") self.assertEqual(response_start["status"], 200) @@ -864,7 +863,7 @@ def test_traceresponse_header(self): set_global_response_propagator(orig) - def test_websocket(self): + async def test_websocket(self): self.scope = { "method": "GET", "type": "websocket", @@ -878,10 +877,10 @@ def test_websocket(self): } app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + await self.get_all_output() span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 6) expected = [ @@ -938,7 +937,7 @@ def test_websocket(self): self.assertEqual(span.kind, expected["kind"]) self.assertDictEqual(dict(span.attributes), expected["attributes"]) - def test_websocket_new_semconv(self): + async def test_websocket_new_semconv(self): self.scope = { "method": "GET", "type": "websocket", @@ -952,10 +951,10 @@ def test_websocket_new_semconv(self): } app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + await self.get_all_output() span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 6) expected = [ @@ -1010,7 +1009,7 @@ def test_websocket_new_semconv(self): self.assertEqual(span.kind, expected["kind"]) self.assertDictEqual(dict(span.attributes), expected["attributes"]) - def test_websocket_both_semconv(self): + async def test_websocket_both_semconv(self): self.scope = { "method": "GET", "type": "websocket", @@ -1024,10 +1023,10 @@ def test_websocket_both_semconv(self): } app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + await self.get_all_output() span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 6) expected = [ @@ -1094,7 +1093,7 @@ def test_websocket_both_semconv(self): self.assertEqual(span.kind, expected["kind"]) self.assertDictEqual(dict(span.attributes), expected["attributes"]) - def test_websocket_traceresponse_header(self): + async def test_websocket_traceresponse_header(self): """Test a traceresponse header is set for websocket messages""" orig = get_global_response_propagator() @@ -1112,10 +1111,10 @@ def test_websocket_traceresponse_header(self): } app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - _, socket_send, *_ = self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + _, socket_send, *_ = await self.get_all_output() span = self.memory_exporter.get_finished_spans()[-1] self.assertEqual(trace_api.SpanKind.SERVER, span.kind) @@ -1134,15 +1133,15 @@ def test_websocket_traceresponse_header(self): set_global_response_propagator(orig) - def test_lifespan(self): + async def test_lifespan(self): self.scope["type"] = "lifespan" app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 0) - def test_hooks(self): + async def test_hooks(self): def server_request_hook(span, scope): span.update_name("name from server hook") @@ -1169,20 +1168,23 @@ def update_expected_hook_results(expected): client_response_hook=client_response_hook, ) self.seed_app(app) - self.send_default_request() - outputs = self.get_all_output() + await self.send_default_request() + outputs = await self.get_all_output() self.validate_outputs( outputs, modifiers=[update_expected_hook_results] ) - def test_asgi_metrics(self): + async def test_asgi_metrics(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() metrics_list = self.memory_metrics_reader.get_metrics_data() number_data_point_seen = False histogram_data_point_seen = False @@ -1211,14 +1213,17 @@ def test_asgi_metrics(self): ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) - def test_asgi_metrics_new_semconv(self): + async def test_asgi_metrics_new_semconv(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() metrics_list = self.memory_metrics_reader.get_metrics_data() number_data_point_seen = False histogram_data_point_seen = False @@ -1247,14 +1252,17 @@ def test_asgi_metrics_new_semconv(self): ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) - def test_asgi_metrics_both_semconv(self): + async def test_asgi_metrics_both_semconv(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() metrics_list = self.memory_metrics_reader.get_metrics_data() number_data_point_seen = False histogram_data_point_seen = False @@ -1283,12 +1291,13 @@ def test_asgi_metrics_both_semconv(self): ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) - def test_basic_metric_success(self): + async def test_basic_metric_success(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) start = default_timer() - self.send_default_request() + await self.send_default_request() duration = max(round((default_timer() - start) * 1000), 0) + await self.get_all_output() expected_duration_attributes = { "http.method": "GET", "http.host": "127.0.0.1", @@ -1330,7 +1339,7 @@ def test_basic_metric_success(self): ) self.assertEqual(point.value, 0) - def test_basic_metric_success_nonrecording_span(self): + async def test_basic_metric_success_nonrecording_span(self): mock_tracer = mock.Mock() mock_span = mock.Mock() mock_span.is_recording.return_value = False @@ -1344,8 +1353,9 @@ def test_basic_metric_success_nonrecording_span(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) start = default_timer() - self.send_default_request() + await self.send_default_request() duration = max(round((default_timer() - start) * 1000), 0) + await self.get_all_output() expected_duration_attributes = { "http.method": "GET", "http.host": "127.0.0.1", @@ -1374,7 +1384,7 @@ def test_basic_metric_success_nonrecording_span(self): self.assertEqual(point.count, 1) if metric.name == "http.server.duration": self.assertAlmostEqual( - duration, point.sum, delta=5 + duration, point.sum, delta=15 ) elif ( metric.name == "http.server.response.size" @@ -1389,12 +1399,13 @@ def test_basic_metric_success_nonrecording_span(self): ) self.assertEqual(point.value, 0) - def test_basic_metric_success_new_semconv(self): + async def test_basic_metric_success_new_semconv(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) start = default_timer() - self.send_default_request() + await self.send_default_request() duration_s = max(default_timer() - start, 0) + await self.get_all_output() expected_duration_attributes = { "http.request.method": "GET", "url.scheme": "http", @@ -1436,13 +1447,14 @@ def test_basic_metric_success_new_semconv(self): ) self.assertEqual(point.value, 0) - def test_basic_metric_success_both_semconv(self): + async def test_basic_metric_success_both_semconv(self): app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) start = default_timer() - self.send_default_request() + await self.send_default_request() duration = max(round((default_timer() - start) * 1000), 0) duration_s = max(default_timer() - start, 0) + await self.get_all_output() expected_duration_attributes_old = { "http.method": "GET", "http.host": "127.0.0.1", @@ -1524,7 +1536,7 @@ def test_basic_metric_success_both_semconv(self): ) self.assertEqual(point.value, 0) - def test_metric_target_attribute(self): + async def test_metric_target_attribute(self): expected_target = "/api/user/{id}" class TestRoute: @@ -1540,7 +1552,8 @@ async def target_asgi(scope, receive, send): app = otel_asgi.OpenTelemetryMiddleware(target_asgi) self.seed_app(app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() metrics_list = self.memory_metrics_reader.get_metrics_data() assertions = 0 for resource_metric in metrics_list.resource_metrics: @@ -1557,7 +1570,7 @@ async def target_asgi(scope, receive, send): assertions += 1 self.assertEqual(assertions, 3) - def test_no_metric_for_websockets(self): + async def test_no_metric_for_websockets(self): self.scope = { "type": "websocket", "http_version": "1.1", @@ -1570,10 +1583,10 @@ def test_no_metric_for_websockets(self): } app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) self.seed_app(app) - self.send_input({"type": "websocket.connect"}) - self.send_input({"type": "websocket.receive", "text": "ping"}) - self.send_input({"type": "websocket.disconnect"}) - self.get_all_output() + await self.send_input({"type": "websocket.connect"}) + await self.send_input({"type": "websocket.receive", "text": "ping"}) + await self.send_input({"type": "websocket.disconnect"}) + await self.get_all_output() self.assertIsNone(self.memory_metrics_reader.get_metrics_data()) @@ -1790,8 +1803,10 @@ def test_collect_target_attribute_fastapi_starlette_invalid(self): ) -class TestWrappedApplication(AsgiTestBase): - def test_mark_span_internal_in_presence_of_span_from_other_framework(self): +class TestWrappedApplication(AsyncAsgiTestBase): + async def test_mark_span_internal_in_presence_of_span_from_other_framework( + self, + ): tracer_provider, exporter = TestBase.create_tracer_provider() tracer = tracer_provider.get_tracer(__name__) app = otel_asgi.OpenTelemetryMiddleware( @@ -1806,7 +1821,8 @@ async def wrapped_app(scope, receive, send): await app(scope, receive, send) self.seed_app(wrapped_app) - self.send_default_request() + await self.send_default_request() + await self.get_all_output() span_list = exporter.get_finished_spans() self.assertEqual(SpanKind.INTERNAL, span_list[0].kind) @@ -1823,11 +1839,11 @@ async def wrapped_app(scope, receive, send): ) -class TestAsgiApplicationRaisingError(AsgiTestBase): +class TestAsgiApplicationRaisingError(AsyncAsgiTestBase): def tearDown(self): pass - def test_asgi_issue_1883(self): + async def test_asgi_value_error_exception(self): """ Test that exception UnboundLocalError local variable 'start' referenced before assignment is not raised See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1883 @@ -1838,11 +1854,9 @@ async def bad_app(_scope, _receive, _send): app = otel_asgi.OpenTelemetryMiddleware(bad_app) self.seed_app(app) - self.send_default_request() + await self.send_default_request() try: - asyncio.get_event_loop().run_until_complete( - self.communicator.stop() - ) + await self.communicator.wait() except ValueError as exc_info: self.assertEqual(exc_info.args[0], "whatever") except Exception as exc_info: # pylint: disable=W0703 From 830397ecbf332e469ff5adc99ba6dea7a79359c5 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 26 Aug 2024 18:54:57 +0200 Subject: [PATCH 159/335] httpx: fix handling of async hooks (#2823) --- CHANGELOG.md | 12 +++-- .../instrumentation/httpx/__init__.py | 13 +++-- .../tests/test_httpx_integration.py | 49 ++++++++++++++++++- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5ce56423a..3dd53582ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,23 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -## Added +### Added - `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537)) -## Breaking changes +### Breaking changes - `opentelemetry-bootstrap` Remove `opentelemetry-instrumentation-aws-lambda` from the defaults instrumentations ([#2786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2786)) -## Fixed +### Fixed +- `opentelemetry-instrumentation-httpx` fix handling of async hooks + ([#2823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2823)) - `opentelemetry-instrumentation-system-metrics` fix `process.runtime.cpu.utilization` values to be shown in range of 0 to 1 - ([2812](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2812)) + ([#2812](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2812)) - `opentelemetry-instrumentation-fastapi` fix `fastapi` auto-instrumentation by removing `fastapi-slim` support, `fastapi-slim` itself is discontinued from maintainers - ([2783](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2783)) + ([#2783](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2783)) - `opentelemetry-instrumentation-aws-lambda` Avoid exception when a handler is not present. ([#2750](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2750)) - `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 43db6c3a82..15ee59a183 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -192,6 +192,7 @@ async def async_response_hook(span, request, response): """ import logging import typing +from asyncio import iscoroutinefunction from types import TracebackType import httpx @@ -731,15 +732,19 @@ def _instrument(self, **kwargs): self._original_async_client = httpx.AsyncClient request_hook = kwargs.get("request_hook") response_hook = kwargs.get("response_hook") - async_request_hook = kwargs.get("async_request_hook", request_hook) - async_response_hook = kwargs.get("async_response_hook", response_hook) + async_request_hook = kwargs.get("async_request_hook") + async_response_hook = kwargs.get("async_response_hook") if callable(request_hook): _InstrumentedClient._request_hook = request_hook - if callable(async_request_hook): + if callable(async_request_hook) and iscoroutinefunction( + async_request_hook + ): _InstrumentedAsyncClient._request_hook = async_request_hook if callable(response_hook): _InstrumentedClient._response_hook = response_hook - if callable(async_response_hook): + if callable(async_response_hook) and iscoroutinefunction( + async_response_hook + ): _InstrumentedAsyncClient._response_hook = async_response_hook tracer_provider = kwargs.get("tracer_provider") _InstrumentedClient._tracer_provider = tracer_provider diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 011b5e57d2..78938eb337 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -780,9 +780,15 @@ def test_custom_tracer_provider(self): HTTPXClientInstrumentor().uninstrument() def test_response_hook(self): + response_hook_key = ( + "async_response_hook" + if asyncio.iscoroutinefunction(self.response_hook) + else "response_hook" + ) + response_hook_kwargs = {response_hook_key: self.response_hook} HTTPXClientInstrumentor().instrument( tracer_provider=self.tracer_provider, - response_hook=self.response_hook, + **response_hook_kwargs, ) client = self.create_client() result = self.perform_request(self.URL, client=client) @@ -823,9 +829,15 @@ def test_response_hook_sync_async_kwargs(self): HTTPXClientInstrumentor().uninstrument() def test_request_hook(self): + request_hook_key = ( + "async_request_hook" + if asyncio.iscoroutinefunction(self.request_hook) + else "request_hook" + ) + request_hook_kwargs = {request_hook_key: self.request_hook} HTTPXClientInstrumentor().instrument( tracer_provider=self.tracer_provider, - request_hook=self.request_hook, + **request_hook_kwargs, ) client = self.create_client() result = self.perform_request(self.URL, client=client) @@ -1214,3 +1226,36 @@ def test_basic_multiple(self): self.perform_request(self.URL, client=self.client) self.perform_request(self.URL, client=self.client2) self.assert_span(num_spans=2) + + def test_async_response_hook_does_nothing_if_not_coroutine(self): + HTTPXClientInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_response_hook=_response_hook, + ) + client = self.create_client() + result = self.perform_request(self.URL, client=client) + + self.assertEqual(result.text, "Hello!") + span = self.assert_span() + self.assertEqual( + dict(span.attributes), + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_URL: self.URL, + SpanAttributes.HTTP_STATUS_CODE: 200, + }, + ) + HTTPXClientInstrumentor().uninstrument() + + def test_async_request_hook_does_nothing_if_not_coroutine(self): + HTTPXClientInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_request_hook=_request_hook, + ) + client = self.create_client() + result = self.perform_request(self.URL, client=client) + + self.assertEqual(result.text, "Hello!") + span = self.assert_span() + self.assertEqual(span.name, "GET") + HTTPXClientInstrumentor().uninstrument() From 5558e78d8c1755fbe36413c03d8fead572bff0d2 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 26 Aug 2024 21:24:53 +0200 Subject: [PATCH 160/335] httpx: decouple tests from proxy related environment variables (#2822) --- .../tests/test_httpx_integration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 78938eb337..27535800cb 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -723,6 +723,7 @@ def test_client_mounts_with_instrumented_transport(self): spans[1].attributes[SpanAttributes.HTTP_URL], https_url ) + @mock.patch.dict("os.environ", {"NO_PROXY": ""}, clear=True) class BaseInstrumentorTest(BaseTest, metaclass=abc.ABCMeta): @abc.abstractmethod def create_client( From 476f6e245a68881796b96f171429a4ce31fed635 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 26 Aug 2024 21:46:08 +0200 Subject: [PATCH 161/335] bootstrap: don't strip \n for last item on listing (#2820) --- .../src/opentelemetry/instrumentation/bootstrap.py | 2 +- opentelemetry-instrumentation/tests/test_bootstrap.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index 6f86a539b2..1cc28abca4 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -119,7 +119,7 @@ def _find_installed_libraries(): def _run_requirements(): logger.setLevel(logging.ERROR) - print("\n".join(_find_installed_libraries()), end="") + print("\n".join(_find_installed_libraries())) def _run_install(): diff --git a/opentelemetry-instrumentation/tests/test_bootstrap.py b/opentelemetry-instrumentation/tests/test_bootstrap.py index bbe2f5623b..4807f0beb7 100644 --- a/opentelemetry-instrumentation/tests/test_bootstrap.py +++ b/opentelemetry-instrumentation/tests/test_bootstrap.py @@ -77,7 +77,7 @@ def test_run_cmd_print(self): bootstrap.run() self.assertEqual( fake_out.getvalue(), - "\n".join(self.installed_libraries), + "\n".join(self.installed_libraries) + "\n", ) @patch("sys.argv", ["bootstrap", "-a", "install"]) From 3ec1b9717ce47eb876dba3e6037b3d8fd72c1d3f Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 27 Aug 2024 10:44:37 -0700 Subject: [PATCH 162/335] Add new maintainers aabmass and xrmx (#2825) Congratulations and welcome @aabmass and @xrmx as new Python maintainers! We greatly appreciate your help and expertise. Co-authored-by: Diego Hurtado --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dcb2ebbba5..d33c1ca4d4 100644 --- a/README.md +++ b/README.md @@ -109,12 +109,10 @@ Meeting notes are available as a public [Google doc](https://docs.google.com/doc Approvers ([@open-telemetry/python-approvers](https://github.com/orgs/open-telemetry/teams/python-approvers)): -- [Aaron Abbott](https://github.com/aabmass), Google - [Emídio Neto](https://github.com/emdneto), Zenvia - [Jeremy Voss](https://github.com/jeremydvoss), Microsoft - [Owais Lone](https://github.com/owais), Splunk - [Pablo Collins](https://github.com/pmcollins), Splunk -- [Riccardo Magliocchetti](https://github.com/xrmx), Elastic - [Sanket Mehta](https://github.com/sanketmehta28), Cisco - [Srikanth Chekuri](https://github.com/srikanthccv), signoz.io - [Tammy Baylis](https://github.com/tammy-baylis-swi), SolarWinds @@ -131,8 +129,10 @@ Emeritus Approvers: Maintainers ([@open-telemetry/python-maintainers](https://github.com/orgs/open-telemetry/teams/python-maintainers)): +- [Aaron Abbott](https://github.com/aabmass), Google - [Diego Hurtado](https://github.com/ocelotl), Lightstep - [Leighton Chen](https://github.com/lzchen), Microsoft +- [Riccardo Magliocchetti](https://github.com/xrmx), Elastic - [Shalev Roda](https://github.com/shalevr), Cisco Emeritus Maintainers: From 5a0540ba8bb5824596e0d42adde77f630555b62b Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 27 Aug 2024 12:08:00 -0600 Subject: [PATCH 163/335] Remove references to test.yml (#2830) * Remove references to test.yml Fixes #2829 * Update scripts/update_sha.py Co-authored-by: Riccardo Magliocchetti --------- Co-authored-by: Riccardo Magliocchetti --- CONTRIBUTING.md | 2 +- README.md | 7 +++++-- scripts/update_sha.py | 18 ++++++++++++------ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d01d43181f..9072a6a641 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -235,7 +235,7 @@ Some of the tox targets install packages from the [OpenTelemetry Python Core Rep CORE_REPO_SHA=c49ad57bfe35cfc69bfa863d74058ca9bec55fc3 tox ``` -The continuous integration overrides that environment variable with as per the configuration [here](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/test.yml#L9). +The continuous integration overrides that environment variable with as per the configuration [here](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/test_0.yml#L14). ## Style Guide diff --git a/README.md b/README.md index d33c1ca4d4..1a2aaf4f8a 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,11 @@ license
- - Build Status + + Build Status 0 + + + Build Status 1 Beta

diff --git a/scripts/update_sha.py b/scripts/update_sha.py index 1c913249a2..c63b9eda9b 100644 --- a/scripts/update_sha.py +++ b/scripts/update_sha.py @@ -22,7 +22,12 @@ API_URL = ( "https://api.github.com/repos/open-telemetry/opentelemetry-python/commits/" ) -WORKFLOW_FILE = ".github/workflows/test.yml" +workflow_files = [ + ".github/workflows/test_0.yml" + ".github/workflows/test_1.yml" + ".github/workflows/misc_0.yml" + ".github/workflows/lint_0.yml" +] def get_sha(branch): @@ -35,11 +40,12 @@ def get_sha(branch): def update_sha(sha): yaml = YAML() yaml.preserve_quotes = True - with open(WORKFLOW_FILE, "r") as file: - workflow = yaml.load(file) - workflow["env"]["CORE_REPO_SHA"] = sha - with open(WORKFLOW_FILE, "w") as file: - yaml.dump(workflow, file) + for workflow_file in workflow_files: + with open(workflow_file, "r") as file: + workflow = yaml.load(file) + workflow["env"]["CORE_REPO_SHA"] = sha + with open(workflow_file, "w") as file: + yaml.dump(workflow, file) def main(): From b0129acbdf35c941f564058a4d5551fea6c8c2d5 Mon Sep 17 00:00:00 2001 From: Jack Gong <93988774+gongbenhua@users.noreply.github.com> Date: Thu, 29 Aug 2024 01:02:42 +0800 Subject: [PATCH 164/335] fix ut in pypy (#2809) --- .../tests/test_fastapi_instrumentation.py | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 91ed514096..634c74af6b 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -530,7 +530,7 @@ def test_basic_metric_success(self): dict(point.attributes), ) self.assertEqual(point.count, 1) - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) if isinstance(point, NumberDataPoint): self.assertDictEqual( expected_requests_count_attributes, @@ -565,7 +565,9 @@ def test_basic_metric_success_new_semconv(self): ) self.assertEqual(point.count, 1) if metric.name == "http.server.request.duration": - self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertAlmostEqual( + duration_s * 0.1, point.sum, places=1 + ) elif metric.name == "http.server.response.body.size": self.assertEqual(25, point.sum) elif metric.name == "http.server.request.body.size": @@ -615,9 +617,11 @@ def test_basic_metric_success_both_semconv(self): for point in list(metric.data.data_points): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) if metric.name == "http.server.request.duration": - self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertAlmostEqual( + duration_s * 0.1, point.sum, places=1 + ) self.assertDictEqual( expected_duration_attributes_new, dict(point.attributes), @@ -635,7 +639,7 @@ def test_basic_metric_success_both_semconv(self): dict(point.attributes), ) elif metric.name == "http.server.duration": - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) self.assertDictEqual( expected_duration_attributes_old, dict(point.attributes), @@ -691,7 +695,7 @@ def test_basic_metric_nonstandard_http_method_success(self): dict(point.attributes), ) self.assertEqual(point.count, 1) - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) if isinstance(point, NumberDataPoint): self.assertDictEqual( expected_requests_count_attributes, @@ -726,7 +730,9 @@ def test_basic_metric_nonstandard_http_method_success_new_semconv(self): ) self.assertEqual(point.count, 1) if metric.name == "http.server.request.duration": - self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertAlmostEqual( + duration_s * 0.1, point.sum, places=1 + ) elif metric.name == "http.server.response.body.size": self.assertEqual(31, point.sum) elif metric.name == "http.server.request.body.size": @@ -777,7 +783,9 @@ def test_basic_metric_nonstandard_http_method_success_both_semconv(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) if metric.name == "http.server.request.duration": - self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertAlmostEqual( + duration_s * 0.1, point.sum, places=1 + ) self.assertDictEqual( expected_duration_attributes_new, dict(point.attributes), @@ -795,7 +803,7 @@ def test_basic_metric_nonstandard_http_method_success_both_semconv(self): dict(point.attributes), ) elif metric.name == "http.server.duration": - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) self.assertDictEqual( expected_duration_attributes_old, dict(point.attributes), @@ -836,7 +844,7 @@ def test_basic_post_request_metric_success(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) if metric.name == "http.server.duration": - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) elif metric.name == "http.server.response.size": self.assertEqual(response_size, point.sum) elif metric.name == "http.server.request.size": @@ -861,7 +869,9 @@ def test_basic_post_request_metric_success_new_semconv(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) if metric.name == "http.server.request.duration": - self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertAlmostEqual( + duration_s * 0.1, point.sum, places=1 + ) elif metric.name == "http.server.response.body.size": self.assertEqual(response_size, point.sum) elif metric.name == "http.server.request.body.size": @@ -887,13 +897,15 @@ def test_basic_post_request_metric_success_both_semconv(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 1) if metric.name == "http.server.request.duration": - self.assertAlmostEqual(duration_s, point.sum, places=1) + self.assertAlmostEqual( + duration_s * 0.1, point.sum, places=1 + ) elif metric.name == "http.server.response.body.size": self.assertEqual(response_size, point.sum) elif metric.name == "http.server.request.body.size": self.assertEqual(request_size, point.sum) elif metric.name == "http.server.duration": - self.assertAlmostEqual(duration, point.sum, delta=40) + self.assertAlmostEqual(duration, point.sum, delta=350) elif metric.name == "http.server.response.size": self.assertEqual(response_size, point.sum) elif metric.name == "http.server.request.size": From 161acbb8ca58f55d0c8da908de369f2cddb880a6 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 28 Aug 2024 12:12:08 -0600 Subject: [PATCH 165/335] Skip generate-workflows when triggered by push (#2836) Fixes #2835 --- .../src/generate_workflows_lib/misc.yml.j2 | 2 +- .github/workflows/misc_0.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index 807da0eb1a..2b0735b432 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -23,7 +23,7 @@ jobs: {%- if job_data == "generate-workflows" %} if: | !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') - && github.actor != 'opentelemetrybot' + && github.actor != 'opentelemetrybot' && github.event_name == 'pull_request' {%- endif %} {%- if job_data == "public-symbols-check" %} if: | diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index f7b9faa9f3..3c3f7bfacf 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -96,7 +96,7 @@ jobs: runs-on: ubuntu-latest if: | !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') - && github.actor != 'opentelemetrybot' + && github.actor != 'opentelemetrybot' && github.event_name == 'pull_request' steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 From ee67ea8ba5380e55be1a9bb1f7e8bc916ff3bdec Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:20:37 -0500 Subject: [PATCH 166/335] Update version to 1.28.0.dev/0.49b0.dev (#2828) * Update version to 1.28.0.dev/0.49b0.dev * Update core SHA --------- Co-authored-by: Diego Hurtado --- .github/workflows/lint_0.yml | 2 +- .github/workflows/misc_0.yml | 2 +- .github/workflows/test_0.yml | 2 +- .github/workflows/test_1.yml | 2 +- CHANGELOG.md | 2 + _template/version.py | 2 +- eachdist.ini | 4 +- .../prometheus_remote_write/version.py | 2 +- .../pyproject.toml | 2 +- .../exporter/richconsole/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/aio_pika/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_client/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_server/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiopg/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asgi/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncio/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncpg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aws_lambda/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto3sqs/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/botocore/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/cassandra/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/celery/version.py | 2 +- .../pyproject.toml | 2 +- .../confluent_kafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/dbapi/version.py | 2 +- .../pyproject.toml | 10 +- .../instrumentation/django/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/elasticsearch/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/falcon/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/fastapi/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/flask/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/grpc/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/httpx/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/jinja2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/kafka/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/logging/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysqlclient/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymemcache/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymongo/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymysql/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/pyramid/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/redis/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/remoulade/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/requests/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlalchemy/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlite3/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/starlette/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/system_metrics/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/threading/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/tornado/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/tortoiseorm/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib3/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/wsgi/version.py | 2 +- .../pyproject.toml | 94 +++++++++--------- .../contrib-instrumentations/version.py | 2 +- opentelemetry-distro/pyproject.toml | 4 +- .../src/opentelemetry/distro/version.py | 2 +- .../instrumentation/bootstrap_gen.py | 98 +++++++++---------- .../opentelemetry/instrumentation/version.py | 2 +- .../processor/baggage/version.py | 2 +- .../propagators/ot_trace/version.py | 2 +- .../resource/detector/container/version.py | 2 +- .../src/opentelemetry/util/http/version.py | 2 +- 114 files changed, 273 insertions(+), 271 deletions(-) diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index b5d20541e5..fa4f2e981a 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 3c3f7bfacf..51cb5afea0 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index d251737227..d216e840ae 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index f7e71dd6b6..dc3afb6464 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dd53582ec..2a18ea7858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 1.27.0/0.48b0 (2024-08-26) + ### Added - `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng diff --git a/_template/version.py b/_template/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/_template/version.py +++ b/_template/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/eachdist.ini b/eachdist.ini index 2bcbde9c7c..79c865b334 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -16,7 +16,7 @@ sortfirst= ext/* [stable] -version=1.27.0.dev +version=1.28.0.dev packages= opentelemetry-sdk @@ -34,7 +34,7 @@ packages= opentelemetry-api [prerelease] -version=0.48b0.dev +version=0.49b0.dev packages= all diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 6d38226160..eb00eb0437 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-sdk ~= 1.12", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "rich>=10.0.0", ] diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index c8be384fe6..65dfe3c7ac 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index cfc53f723a..fbe663a50b 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py index aa0c1a911f..49b83ce95e 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 6d62bd7956..a8e912e68d 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 404bc9c445..3a583db3dd 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 480ca75df7..45c436aad4 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ dependencies = [ "asgiref ~= 3.0", "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index cda5403ef5..36ed960392 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.14", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 820c86070d..5a6632a028 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index b512faa3eb..debc3ce033 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0.1", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index 3abda7b175..a2bdba302f 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index cbbf9cd679..72dc38cbec 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index f286e7fc7b..797145b728 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index b2ee19bdd2..3e785d1e8b 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 0d302a4206..9f0f594581 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 13433ba9e2..2edfdeb038 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-api ~= 1.12", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index 991c7bb8af..bfa63dbcad 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py index e0bef4b1e3..79e27849a4 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index a8b53820bc..27cdf157c4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -26,15 +26,15 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-wsgi == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-wsgi == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] asgi = [ - "opentelemetry-instrumentation-asgi == 0.48b0.dev", + "opentelemetry-instrumentation-asgi == 0.49b0.dev", ] instruments = [ "django >= 1.10", diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 29d7bec6cc..e086d2c335 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 6f505f60ae..f118ff4296 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-wsgi == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-wsgi == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", "packaging >= 20.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 3017dc040a..89f6602e86 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-asgi == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-asgi == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index ffafdbacc6..0e74ca331f 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-wsgi == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-wsgi == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", "packaging >= 21.0", "importlib-metadata >= 4.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index d0a7d54298..e1956aeeea 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 5e4629e281..599091716b 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index f74b8ca488..40159c3485 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index c256c71b94..d47672fa07 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 2c1b2ad897..62656bea22 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py index e0bef4b1e3..79e27849a4 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 3c7d0c9166..629ab5325e 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index 0ede691e36..0cc4553384 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 145439b242..bc01323ee4 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", "wrapt >= 1.0.0, < 2.0.0", diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 717257821d..513064ae7f 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 7db83dcc5c..592c15b4db 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 47df236c42..c20ffd3dee 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index ccd75ffeaa..61f4fd2b72 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 08ee94fd9e..9e1bc1a881 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 9da43f444c..2a559e6c60 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-wsgi == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-wsgi == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index d39bda20a5..c262363fab 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.12.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 8b2b3679a9..7f3041b887 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index 88996d2540..dafe3b4d3a 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index 21021fb590..d6cc3f71d9 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", "packaging >= 21.0", "wrapt >= 1.11.2", ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index e86fb99235..60ec47b16e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-dbapi == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-dbapi == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py index e0bef4b1e3..79e27849a4 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 6e6d370b53..9cdd968ca0 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-instrumentation-asgi == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation-asgi == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 6a1e83912f..a405c668f7 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-api ~= 1.11", "psutil >= 5.9.0, < 7", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 16088e7de3..43f92d2034 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index 0096deb8fd..f3f9a4b4fc 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 04d81e1894..82ccbc6a79 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 4f0d2681f9..97b611b095 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index e0bef4b1e3..79e27849a4 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 03c9f26fbc..3c1eaaa6d0 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index b38f1829aa..a5e81ee8e5 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", - "opentelemetry-semantic-conventions == 0.48b0.dev", - "opentelemetry-util-http == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-util-http == 0.49b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 6c7716bad2..9c40f9c2a3 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -29,53 +29,53 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation-aio-pika==0.48b0.dev", - "opentelemetry-instrumentation-aiohttp-client==0.48b0.dev", - "opentelemetry-instrumentation-aiohttp-server==0.48b0.dev", - "opentelemetry-instrumentation-aiopg==0.48b0.dev", - "opentelemetry-instrumentation-asgi==0.48b0.dev", - "opentelemetry-instrumentation-asyncio==0.48b0.dev", - "opentelemetry-instrumentation-asyncpg==0.48b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.48b0.dev", - "opentelemetry-instrumentation-boto==0.48b0.dev", - "opentelemetry-instrumentation-boto3sqs==0.48b0.dev", - "opentelemetry-instrumentation-botocore==0.48b0.dev", - "opentelemetry-instrumentation-cassandra==0.48b0.dev", - "opentelemetry-instrumentation-celery==0.48b0.dev", - "opentelemetry-instrumentation-confluent-kafka==0.48b0.dev", - "opentelemetry-instrumentation-dbapi==0.48b0.dev", - "opentelemetry-instrumentation-django==0.48b0.dev", - "opentelemetry-instrumentation-elasticsearch==0.48b0.dev", - "opentelemetry-instrumentation-falcon==0.48b0.dev", - "opentelemetry-instrumentation-fastapi==0.48b0.dev", - "opentelemetry-instrumentation-flask==0.48b0.dev", - "opentelemetry-instrumentation-grpc==0.48b0.dev", - "opentelemetry-instrumentation-httpx==0.48b0.dev", - "opentelemetry-instrumentation-jinja2==0.48b0.dev", - "opentelemetry-instrumentation-kafka-python==0.48b0.dev", - "opentelemetry-instrumentation-logging==0.48b0.dev", - "opentelemetry-instrumentation-mysql==0.48b0.dev", - "opentelemetry-instrumentation-mysqlclient==0.48b0.dev", - "opentelemetry-instrumentation-pika==0.48b0.dev", - "opentelemetry-instrumentation-psycopg==0.48b0.dev", - "opentelemetry-instrumentation-psycopg2==0.48b0.dev", - "opentelemetry-instrumentation-pymemcache==0.48b0.dev", - "opentelemetry-instrumentation-pymongo==0.48b0.dev", - "opentelemetry-instrumentation-pymysql==0.48b0.dev", - "opentelemetry-instrumentation-pyramid==0.48b0.dev", - "opentelemetry-instrumentation-redis==0.48b0.dev", - "opentelemetry-instrumentation-remoulade==0.48b0.dev", - "opentelemetry-instrumentation-requests==0.48b0.dev", - "opentelemetry-instrumentation-sqlalchemy==0.48b0.dev", - "opentelemetry-instrumentation-sqlite3==0.48b0.dev", - "opentelemetry-instrumentation-starlette==0.48b0.dev", - "opentelemetry-instrumentation-system-metrics==0.48b0.dev", - "opentelemetry-instrumentation-threading==0.48b0.dev", - "opentelemetry-instrumentation-tornado==0.48b0.dev", - "opentelemetry-instrumentation-tortoiseorm==0.48b0.dev", - "opentelemetry-instrumentation-urllib==0.48b0.dev", - "opentelemetry-instrumentation-urllib3==0.48b0.dev", - "opentelemetry-instrumentation-wsgi==0.48b0.dev", + "opentelemetry-instrumentation-aio-pika==0.49b0.dev", + "opentelemetry-instrumentation-aiohttp-client==0.49b0.dev", + "opentelemetry-instrumentation-aiohttp-server==0.49b0.dev", + "opentelemetry-instrumentation-aiopg==0.49b0.dev", + "opentelemetry-instrumentation-asgi==0.49b0.dev", + "opentelemetry-instrumentation-asyncio==0.49b0.dev", + "opentelemetry-instrumentation-asyncpg==0.49b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.49b0.dev", + "opentelemetry-instrumentation-boto==0.49b0.dev", + "opentelemetry-instrumentation-boto3sqs==0.49b0.dev", + "opentelemetry-instrumentation-botocore==0.49b0.dev", + "opentelemetry-instrumentation-cassandra==0.49b0.dev", + "opentelemetry-instrumentation-celery==0.49b0.dev", + "opentelemetry-instrumentation-confluent-kafka==0.49b0.dev", + "opentelemetry-instrumentation-dbapi==0.49b0.dev", + "opentelemetry-instrumentation-django==0.49b0.dev", + "opentelemetry-instrumentation-elasticsearch==0.49b0.dev", + "opentelemetry-instrumentation-falcon==0.49b0.dev", + "opentelemetry-instrumentation-fastapi==0.49b0.dev", + "opentelemetry-instrumentation-flask==0.49b0.dev", + "opentelemetry-instrumentation-grpc==0.49b0.dev", + "opentelemetry-instrumentation-httpx==0.49b0.dev", + "opentelemetry-instrumentation-jinja2==0.49b0.dev", + "opentelemetry-instrumentation-kafka-python==0.49b0.dev", + "opentelemetry-instrumentation-logging==0.49b0.dev", + "opentelemetry-instrumentation-mysql==0.49b0.dev", + "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", + "opentelemetry-instrumentation-pika==0.49b0.dev", + "opentelemetry-instrumentation-psycopg==0.49b0.dev", + "opentelemetry-instrumentation-psycopg2==0.49b0.dev", + "opentelemetry-instrumentation-pymemcache==0.49b0.dev", + "opentelemetry-instrumentation-pymongo==0.49b0.dev", + "opentelemetry-instrumentation-pymysql==0.49b0.dev", + "opentelemetry-instrumentation-pyramid==0.49b0.dev", + "opentelemetry-instrumentation-redis==0.49b0.dev", + "opentelemetry-instrumentation-remoulade==0.49b0.dev", + "opentelemetry-instrumentation-requests==0.49b0.dev", + "opentelemetry-instrumentation-sqlalchemy==0.49b0.dev", + "opentelemetry-instrumentation-sqlite3==0.49b0.dev", + "opentelemetry-instrumentation-starlette==0.49b0.dev", + "opentelemetry-instrumentation-system-metrics==0.49b0.dev", + "opentelemetry-instrumentation-threading==0.49b0.dev", + "opentelemetry-instrumentation-tornado==0.49b0.dev", + "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", + "opentelemetry-instrumentation-urllib==0.49b0.dev", + "opentelemetry-instrumentation-urllib3==0.49b0.dev", + "opentelemetry-instrumentation-wsgi==0.49b0.dev", ] [project.urls] diff --git a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py +++ b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 2397e9182a..686eeaba95 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -27,13 +27,13 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.48b0.dev", + "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-sdk ~= 1.13", ] [project.optional-dependencies] otlp = [ - "opentelemetry-exporter-otlp == 1.27.0.dev", + "opentelemetry-exporter-otlp == 1.28.0.dev", ] [project.entry-points.opentelemetry_configurator] diff --git a/opentelemetry-distro/src/opentelemetry/distro/version.py b/opentelemetry-distro/src/opentelemetry/distro/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/version.py +++ b/opentelemetry-distro/src/opentelemetry/distro/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index c31863bd31..8c4293f261 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -18,179 +18,179 @@ libraries = [ { "library": "aio_pika >= 7.2.0, < 10.0.0", - "instrumentation": "opentelemetry-instrumentation-aio-pika==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-aio-pika==0.49b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.49b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.49b0.dev", }, { "library": "aiopg >= 0.13.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiopg==0.49b0.dev", }, { "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-asgi==0.49b0.dev", }, { "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncpg==0.49b0.dev", }, { "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto==0.49b0.dev", }, { "library": "boto3 ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.49b0.dev", }, { "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.49b0.dev", }, { "library": "cassandra-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.49b0.dev", }, { "library": "scylla-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.49b0.dev", }, { "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-celery==0.49b0.dev", }, { "library": "confluent-kafka >= 1.8.2, <= 2.4.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.49b0.dev", }, { "library": "django >= 1.10", - "instrumentation": "opentelemetry-instrumentation-django==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-django==0.49b0.dev", }, { "library": "elasticsearch >= 6.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.49b0.dev", }, { "library": "falcon >= 1.4.1, < 3.1.2", - "instrumentation": "opentelemetry-instrumentation-falcon==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-falcon==0.49b0.dev", }, { "library": "fastapi ~= 0.58", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.49b0.dev", }, { "library": "flask >= 1.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-flask==0.49b0.dev", }, { "library": "grpcio ~= 1.27", - "instrumentation": "opentelemetry-instrumentation-grpc==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-grpc==0.49b0.dev", }, { "library": "httpx >= 0.18.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-httpx==0.49b0.dev", }, { "library": "jinja2 >= 2.7, < 4.0", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-jinja2==0.49b0.dev", }, { "library": "kafka-python >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.49b0.dev", }, { "library": "kafka-python-ng >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.49b0.dev", }, { "library": "mysql-connector-python >= 8.0, < 10.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysql==0.49b0.dev", }, { "library": "mysqlclient < 3", - "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", }, { "library": "pika >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-pika==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-pika==0.49b0.dev", }, { "library": "psycopg >= 3.1.0", - "instrumentation": "opentelemetry-instrumentation-psycopg==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg==0.49b0.dev", }, { "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.49b0.dev", }, { "library": "pymemcache >= 1.3.5, < 5", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymemcache==0.49b0.dev", }, { "library": "pymongo >= 3.1, < 5.0", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymongo==0.49b0.dev", }, { "library": "PyMySQL < 2", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymysql==0.49b0.dev", }, { "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-pyramid==0.49b0.dev", }, { "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-redis==0.49b0.dev", }, { "library": "remoulade >= 0.50", - "instrumentation": "opentelemetry-instrumentation-remoulade==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-remoulade==0.49b0.dev", }, { "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-requests==0.49b0.dev", }, { "library": "sqlalchemy", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.49b0.dev", }, { "library": "starlette ~= 0.13.0", - "instrumentation": "opentelemetry-instrumentation-starlette==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-starlette==0.49b0.dev", }, { "library": "psutil >= 5", - "instrumentation": "opentelemetry-instrumentation-system-metrics==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-system-metrics==0.49b0.dev", }, { "library": "tornado >= 5.1.1", - "instrumentation": "opentelemetry-instrumentation-tornado==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-tornado==0.49b0.dev", }, { "library": "tortoise-orm >= 0.17.0", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", }, { "library": "pydantic >= 1.10.2", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", }, { "library": "urllib3 >= 1.0.0, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.48b0.dev", + "instrumentation": "opentelemetry-instrumentation-urllib3==0.49b0.dev", }, ] default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.48b0.dev", - "opentelemetry-instrumentation-dbapi==0.48b0.dev", - "opentelemetry-instrumentation-logging==0.48b0.dev", - "opentelemetry-instrumentation-sqlite3==0.48b0.dev", - "opentelemetry-instrumentation-threading==0.48b0.dev", - "opentelemetry-instrumentation-urllib==0.48b0.dev", - "opentelemetry-instrumentation-wsgi==0.48b0.dev", + "opentelemetry-instrumentation-asyncio==0.49b0.dev", + "opentelemetry-instrumentation-dbapi==0.49b0.dev", + "opentelemetry-instrumentation-logging==0.49b0.dev", + "opentelemetry-instrumentation-sqlite3==0.49b0.dev", + "opentelemetry-instrumentation-threading==0.49b0.dev", + "opentelemetry-instrumentation-urllib==0.49b0.dev", + "opentelemetry-instrumentation-wsgi==0.49b0.dev", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py +++ b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py index 4d21fcb843..ee5a6342e7 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.48b0.dev" +__version__ = "0.49b0.dev" From f8a4f1ebf8b22a983c4bc8937268c2fc2b61beb9 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:54:08 -0500 Subject: [PATCH 167/335] Copy change log updates from release/v1.27.x-0.48bx (#2839) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a18ea7858..d4c03d3b38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -## Version 1.27.0/0.48b0 (2024-08-26) +## Version 1.27.0/0.48b0 () ### Added From f7878e761373f70a67acac1c8efa16e89b9c1974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:07:04 -0300 Subject: [PATCH 168/335] fix core repo sha in workflows (#2842) --- .github/workflows/lint_0.yml | 2 +- .github/workflows/misc_0.yml | 2 +- .github/workflows/test_0.yml | 2 +- .github/workflows/test_1.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index fa4f2e981a..b5d20541e5 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 51cb5afea0..3c3f7bfacf 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index d216e840ae..d251737227 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index dc3afb6464..f7e71dd6b6 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 8368b6305b4246aafa4ffa7d4890a692d1010b6e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w From 98958b6f1ef09d332e13ea1d7bc308f8e9edd351 Mon Sep 17 00:00:00 2001 From: JianQiao Date: Fri, 30 Aug 2024 18:42:33 +0800 Subject: [PATCH 169/335] Fix description of http.server.duration and http.server.request.duration (#2817) * fix httpserverduration and httpserverrequestduration Signed-off-by: Steven Pan * add change log --------- Signed-off-by: Steven Pan --- CHANGELOG.md | 2 ++ .../instrumentation/aiohttp_server/__init__.py | 2 +- .../src/opentelemetry/instrumentation/asgi/__init__.py | 2 +- .../src/opentelemetry/instrumentation/django/__init__.py | 2 +- .../src/opentelemetry/instrumentation/falcon/__init__.py | 2 +- .../src/opentelemetry/instrumentation/flask/__init__.py | 8 ++++---- .../opentelemetry/instrumentation/pyramid/callbacks.py | 2 +- .../src/opentelemetry/instrumentation/tornado/__init__.py | 2 +- .../src/opentelemetry/instrumentation/wsgi/__init__.py | 4 ++-- 9 files changed, 14 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c03d3b38..003f8054f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2563](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2563)) - `opentelemetry-instrumentation` fix `http.host` new http semantic convention mapping to depend on `kind` of span ([#2814](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2814)) +- `opentelemetry-instrumentation` Fix the description of `http.server.duration` and `http.server.request.duration` + ([#2753](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2753)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py index 659ff24af6..6db7719c76 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py @@ -207,7 +207,7 @@ async def middleware(request, handler): duration_histogram = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP server requests.", + description="Measures the duration of inbound HTTP requests.", ) active_requests_counter = meter.create_up_down_counter( diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 295eb2a043..420fd512d6 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -579,7 +579,7 @@ def __init__( self.duration_histogram_old = self.meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP server requests.", + description="Measures the duration of inbound HTTP requests.", ) self.duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py index 651df12043..d37c45993c 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py @@ -344,7 +344,7 @@ def _instrument(self, **kwargs): _DjangoMiddleware._duration_histogram_old = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP server requests.", + description="Measures the duration of inbound HTTP requests.", ) _DjangoMiddleware._duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 1a252b9a16..2dce5f1ef5 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -268,7 +268,7 @@ def __init__(self, *args, **kwargs): self.duration_histogram = self._otel_meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP server requests.", + description="Measures the duration of inbound HTTP requests.", ) self.active_requests_counter = self._otel_meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, 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 0093715ae1..192e044655 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -568,14 +568,14 @@ def __init__(self, *args, **kwargs): duration_histogram_old = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="measures the duration of the inbound HTTP request", + description="Measures the duration of inbound HTTP requests.", ) duration_histogram_new = None if _report_new(_InstrumentedFlask._sem_conv_opt_in_mode): duration_histogram_new = meter.create_histogram( name=HTTP_SERVER_REQUEST_DURATION, unit="s", - description="measures the duration of the inbound HTTP request", + description="Duration of HTTP server requests.", ) active_requests_counter = meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, @@ -701,14 +701,14 @@ def instrument_app( duration_histogram_old = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="measures the duration of the inbound HTTP request", + description="Measures the duration of inbound HTTP requests.", ) duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): duration_histogram_new = meter.create_histogram( name=HTTP_SERVER_REQUEST_DURATION, unit="s", - description="measures the duration of the inbound HTTP request", + description="Duration of HTTP server requests.", ) active_requests_counter = meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index 09f1645384..6a526f2235 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -141,7 +141,7 @@ def trace_tween_factory(handler, registry): duration_histogram = meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP server requests.", + description="Measures the duration of inbound HTTP requests.", ) active_requests_counter = meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py index 1b56db3876..0b5e06b526 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -296,7 +296,7 @@ def _create_server_histograms(meter) -> Dict[str, Histogram]: MetricInstruments.HTTP_SERVER_DURATION: meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="Duration of HTTP server requests.", + description="Measures the duration of inbound HTTP requests.", ), MetricInstruments.HTTP_SERVER_REQUEST_SIZE: meter.create_histogram( name=MetricInstruments.HTTP_SERVER_REQUEST_SIZE, diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 88704f35ab..c0384d594b 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -571,14 +571,14 @@ def __init__( self.duration_histogram_old = self.meter.create_histogram( name=MetricInstruments.HTTP_SERVER_DURATION, unit="ms", - description="measures the duration of the inbound HTTP request", + description="Measures the duration of inbound HTTP requests.", ) self.duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): self.duration_histogram_new = self.meter.create_histogram( name=HTTP_SERVER_REQUEST_DURATION, unit="s", - description="measures the duration of the inbound HTTP request", + description="Duration of HTTP server requests.", ) # We don't need a separate active request counter for old/new semantic conventions # because the new attributes are a subset of the old attributes From f5868df7f898d5134d8e38b81ee99b5a2d04bc36 Mon Sep 17 00:00:00 2001 From: Karoline Pauls <43616133+karolinepauls@users.noreply.github.com> Date: Mon, 2 Sep 2024 16:06:57 +0100 Subject: [PATCH 170/335] opentelemetry-instrumentation-asyncio: package name typo (#2844) --- .../src/opentelemetry/instrumentation/asyncio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index ae10560861..e83f384a8c 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -14,7 +14,7 @@ """ .. asyncio: https://github.com/python/asyncio -The opentelemetry-instrumentation-asycnio package allows tracing asyncio applications. +The opentelemetry-instrumentation-asyncio package allows tracing asyncio applications. The metric for coroutine, future, is generated even if there is no setting to generate a span. Run instrumented application From 40c3363e9d30dbafac81f7ee43576552050e5b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:28:53 -0300 Subject: [PATCH 171/335] bump asgiref to 3.8.1 in test-requirements (#2841) Co-authored-by: Riccardo Magliocchetti --- .../test-requirements.txt | 2 +- .../opentelemetry-exporter-richconsole/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-aiopg/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-asgi/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-dbapi/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-ng.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-4.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-redis/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-wsgi/test-requirements.txt | 2 +- opentelemetry-distro/test-requirements.txt | 2 +- opentelemetry-instrumentation/test-requirements.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements.txt | 2 +- .../opentelemetry-propagator-ot-trace/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-sdk-extension-aws/test-requirements.txt | 2 +- tox.ini | 2 +- util/opentelemetry-util-http/test-requirements.txt | 4 ++-- 83 files changed, 84 insertions(+), 84 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index f7e66ddd13..5836dc9764 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 charset-normalizer==3.3.2 # We can drop this after bumping baseline to pypy-39 diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index dee47c7880..0ef562821f 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 flaky==3.7.0 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index a08f6427db..de853e16c9 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -1,6 +1,6 @@ aio-pika==7.2.0 aiormq==6.2.3 -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index 99b5fdfd1f..dbfb89fe82 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -1,6 +1,6 @@ aio-pika==8.3.0 aiormq==6.6.4 -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 7051299461..6a95bd69f0 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -1,6 +1,6 @@ aio-pika==9.0.5 aiormq==6.7.1 -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index de5e8b310f..82e742a1f4 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -1,6 +1,6 @@ aio-pika==9.4.1 aiormq==6.8.0 -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index be0311238f..dee4736133 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -1,6 +1,6 @@ aiohttp==3.10.2 aiosignal==1.3.1 -asgiref==3.7.2 +asgiref==3.8.1 async-timeout==4.0.3 blinker==1.7.0 certifi==2024.7.4 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index 9cd6a3c111..e6dff52db9 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -1,6 +1,6 @@ aiohttp==3.10.2 aiosignal==1.3.1 -asgiref==3.7.2 +asgiref==3.8.1 async-timeout==4.0.3 Deprecated==1.2.14 frozenlist==1.4.1 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index bc61c3d6fc..1443104081 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -1,5 +1,5 @@ aiopg==1.4.0 -asgiref==3.7.2 +asgiref==3.8.1 async-timeout==4.0.3 Deprecated==1.2.14 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index ebe439d1d2..18a11500e1 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index a196e8d4e3..7f20d1497c 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index badc61cde8..60cef50a7a 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 async-timeout==4.0.3 asyncpg==0.29.0 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index 6540349a2e..8d9fe19483 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index ab4819b538..fe6467d1c4 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 boto==2.49.0 boto3==1.34.44 botocore==1.34.44 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index c5942b6a72..d8a9c38315 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 boto3==1.34.44 botocore==1.34.44 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index e45fa6ba44..a89fdf2e30 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 aws-xray-sdk==2.12.1 boto3==1.28.80 botocore==1.31.80 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index dc2090627d..189b2f65d0 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 cassandra-driver==3.29.0 click==8.1.7 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index 401921f5e4..fcf838fc32 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -1,5 +1,5 @@ amqp==5.2.0 -asgiref==3.7.2 +asgiref==3.8.1 backports.zoneinfo==0.2.1 billiard==4.2.0 celery==5.3.6 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 1c5aad2c07..76b2f03d12 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -1,5 +1,5 @@ amqp==5.2.0 -asgiref==3.7.2 +asgiref==3.8.1 billiard==4.2.0 celery==5.3.6 click==8.1.7 diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 5400e507f5..f78f498620 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 confluent-kafka==2.4.0 Deprecated==1.2.14 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index 0d98d28069..f76b488d90 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index 5f22f2cadb..9d7ee964fe 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 Django==2.2.28 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index 0a042a1bf5..9c21d2dfd4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 Django==3.2.25 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 4f49efb39e..d3a55aae34 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 backports.zoneinfo==0.2.1 Deprecated==1.2.14 Django==4.2.15 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index 9be1266014..89923379d3 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 Django==4.2.15 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index 07ea98e4d6..55eabe1ef5 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 elasticsearch==6.8.2 elasticsearch-dsl==6.4.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index 228601485d..2fab7287ad 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 elasticsearch==7.17.9 elasticsearch-dsl==7.4.1 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index 272675c119..5f2ccd41ac 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 elasticsearch==8.13.1 elasticsearch-dsl==8.13.1 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index d0f6381b42..6967c57b6d 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 falcon==1.4.1 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index 5a84f224f1..e535925b14 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 falcon==2.0.0 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index 0790e8a4cb..30d21e2773 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 falcon==3.1.1 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 00242d5410..927e68f94e 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -1,6 +1,6 @@ annotated-types==0.6.0 anyio==4.3.0 -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index a222e011a7..0bd176848d 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 click==8.1.7 Deprecated==1.2.14 Flask==2.1.3 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index e799218273..d73ab497b5 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 click==8.1.7 Deprecated==1.2.14 Flask==2.2.0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 91ae64700c..299a347d66 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 blinker==1.7.0 click==8.1.7 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt index 457c285715..83ec6e8e70 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 grpcio==1.62.0 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index 221359e184..d77d67148a 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 grpcio==1.63.0 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index 35ebe6b954..28b475a3a4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -1,5 +1,5 @@ anyio==3.7.1 -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 Deprecated==1.2.14 exceptiongroup==1.2.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index c70677f06b..42c032a546 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -1,5 +1,5 @@ anyio==4.3.0 -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 Deprecated==1.2.14 exceptiongroup==1.2.0 diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index 05d94d6fb0..59eabe6997 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt index 7b587031ec..05e169a7e3 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index 4adc515de7..6582cf875b 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index eca8ce5f34..c0d2f044c8 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt index 75ee9797b8..bf93434850 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt index dd609e594a..1a58c16a05 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index 534c7869cb..8c3ed72f35 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index cc874af2cc..e06bc0b395 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index 4a09147744..8928f655c8 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index e60531b112..42bbac77d9 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 backports.zoneinfo==0.2.1 Deprecated==1.2.14 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index 6ad211f9c0..1f7fb59f2d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index 4d6682b3d6..aa98fa93d0 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index 28a62d84b4..2c6e0e2749 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index 4be0dbee52..36db8d4416 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index f07d79374a..3e0359f731 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index 4e4871147c..916c9c9c3a 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index 28fe27f0ef..e90a138ff8 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index eb41ee6bd9..6c8de553b6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 dnspython==2.6.1 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index 8338f79b65..7ad69f2b81 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index aa387f8177..6f33f33449 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 hupper==1.12.1 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 43d4bd9788..7b8d8459b7 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 async-timeout==4.0.3 Deprecated==1.2.14 fakeredis==2.23.3 diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index 727c15ec4e..b850e46f9f 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 03d0a793a6..9f40c6d5b2 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index 407222e8f6..45992bc2e1 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 cffi==1.15.1 Deprecated==1.2.14 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index 9b1b15debc..eb1ee371b7 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -1,5 +1,5 @@ aiosqlite==0.20.0 -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 greenlet==3.0.3 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index 8c98e702b4..e260861814 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 1d5b91e188..d81a15a40c 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -1,5 +1,5 @@ anyio==4.3.0 -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index 506499ea13..76f2f2a4e7 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index 45ee66cf01..2d13857e9e 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index fb542966de..236c45f87b 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 blinker==1.7.0 certifi==2024.7.4 charset-normalizer==3.3.2 diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index cb31845d66..31b044a2f3 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -1,6 +1,6 @@ aiosqlite==0.17.0 annotated-types==0.6.0 -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index 9e11fb272f..06bc8322dc 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 httpretty==1.1.4 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index 1d6ebc18af..e7392b0c31 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 httpretty==1.1.4 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 06df34d16b..21cb3acbe6 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 httpretty==1.1.4 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index 0f7c7ced73..d63bd5a637 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index d9190daa26..050054c39b 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index 6cd12fad24..31f1ef76ab 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index 8589a794a4..4587d87629 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index 0a72c3c823..b556c4f0cc 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements.txt b/resource/opentelemetry-resource-detector-azure/test-requirements.txt index 028c41e65d..2b29359fbb 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/resource/opentelemetry-resource-detector-container/test-requirements.txt b/resource/opentelemetry-resource-detector-container/test-requirements.txt index 8a926fff71..f7b5b71fcf 100644 --- a/resource/opentelemetry-resource-detector-container/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-container/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt index 27199627a1..1fa968a8b3 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 diff --git a/tox.ini b/tox.ini index 8552948b6b..600929a6ec 100644 --- a/tox.ini +++ b/tox.ini @@ -1190,7 +1190,7 @@ basepython: python3 deps = aiopg==1.4.0 amqp==5.2.0 - asgiref==3.7.2 + asgiref==3.8.1 async-timeout==4.0.3 asyncpg==0.29.0 attrs==23.2.0 diff --git a/util/opentelemetry-util-http/test-requirements.txt b/util/opentelemetry-util-http/test-requirements.txt index cb1ffe135b..1769daa094 100644 --- a/util/opentelemetry-util-http/test-requirements.txt +++ b/util/opentelemetry-util-http/test-requirements.txt @@ -1,4 +1,4 @@ -asgiref==3.7.2 +asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 @@ -8,4 +8,4 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.10.0 --e opentelemetry-instrumentation \ No newline at end of file +-e opentelemetry-instrumentation From d6e667f3eb975a369f5e40eea05add3bb701d425 Mon Sep 17 00:00:00 2001 From: Blueswen Date: Wed, 4 Sep 2024 19:55:00 +0800 Subject: [PATCH 172/335] Update README.rst (#2849) The URL link is incorrect; it should be a repository in the open-telemetry account. --- opentelemetry-instrumentation/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-instrumentation/README.rst b/opentelemetry-instrumentation/README.rst index 6f66edb623..3ed88c213f 100644 --- a/opentelemetry-instrumentation/README.rst +++ b/opentelemetry-instrumentation/README.rst @@ -40,7 +40,7 @@ to figure out which instrumentation packages the user might want to install. By prints out a list of the default and detected instrumentation packages that can be added to a requirements.txt file. It also supports installing the packages when run with :code:`--action=install` or :code:`-a install` flag. All default and detectable -instrumentation packages are defined `here `. +instrumentation packages are defined `here `. opentelemetry-instrument From 6c5730f31a430da360c6d1cf8abc0ee3166a0376 Mon Sep 17 00:00:00 2001 From: rama280290 <131746267+rama280290@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:54:25 +0530 Subject: [PATCH 173/335] Update test_jinja2.py (#2491) Cross-site scripting (XSS) attacks can occur if untrusted input is not escaped. This applies to templates as well as code. The jinja2 templates may be vulnerable to XSS if the environment has autoescape set to False. Unfortunately, jinja2 sets autoescape to False by default. Explicitly setting autoescape to True when creating an Environment object will prevent this. Signed-off-by: Rajendran, Ramasubramanian --- .../opentelemetry-instrumentation-jinja2/tests/test_jinja2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py b/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py index 26ba98e69b..98344c47e4 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/tests/test_jinja2.py @@ -143,7 +143,7 @@ def test_generate_inline_template(self): def test_file_template_with_root(self): with self.tracer.start_as_current_span("root"): loader = jinja2.loaders.FileSystemLoader(TMPL_DIR) - env = jinja2.Environment(loader=loader) + env = jinja2.Environment(loader=loader, autoescape=True) template = env.get_template("template.html") self.assertEqual( template.render(name="Jinja"), "Message: Hello Jinja!" @@ -164,7 +164,7 @@ def test_file_template_with_root(self): def test_file_template(self): loader = jinja2.loaders.FileSystemLoader(TMPL_DIR) - env = jinja2.Environment(loader=loader) + env = jinja2.Environment(loader=loader, autoescape=True) template = env.get_template("template.html") self.assertEqual( template.render(name="Jinja"), "Message: Hello Jinja!" From afb7f54b50faf5444ba6498fe6cf7c13181f9cd2 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 4 Sep 2024 08:06:58 -0600 Subject: [PATCH 174/335] Remove ocelotl from component owners (#2848) --- .github/component_owners.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index b092d5d2c3..e3ca06b450 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -45,27 +45,13 @@ components: instrumentation/opentelemetry-instrumentation-urllib: - shalevr - - ocelotl instrumentation/opentelemetry-instrumentation-urllib3: - shalevr - - ocelotl instrumentation/opentelemetry-instrumentation-sqlalchemy: - shalevr - instrumentation/opentelemetry-instrumentation-flask: - - ocelotl - - instrumentation/opentelemetry-instrumentation-jinja2: - - ocelotl - - instrumentation/opentelemetry-instrumentation-logging: - - ocelotl - - instrumentation/opentelemetry-instrumentation-requests: - - ocelotl - instrumentation/opentelemetry-instrumentation-cassandra: - mattcontinisio From f1d91097d88335ac39c8b3ed949e224d80f6105e Mon Sep 17 00:00:00 2001 From: kaushik95 Date: Wed, 4 Sep 2024 22:09:17 +0530 Subject: [PATCH 175/335] 973 opentelemetry instrumentation psycopg2 (#2840) --- .../tests/test_psycopg2_integration.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py index 369d63d5cf..6671073043 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py @@ -18,6 +18,7 @@ import psycopg2 import opentelemetry.instrumentation.psycopg2 +from opentelemetry import trace from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor from opentelemetry.sdk import resources from opentelemetry.test.test_base import TestBase @@ -269,3 +270,14 @@ def test_sqlcommenter_disabled(self, event_mocked): cursor.execute(query) kwargs = event_mocked.call_args[1] self.assertEqual(kwargs["enable_commenter"], False) + + def test_no_op_tracer_provider(self): + Psycopg2Instrumentor().instrument( + tracer_provider=trace.NoOpTracerProvider() + ) + cnx = psycopg2.connect(database="test") + cursor = cnx.cursor() + query = "SELECT * FROM test" + cursor.execute(query) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) From 9cced9757ace5688de08ae1d58acf87c7da92cf8 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 4 Sep 2024 19:45:06 +0200 Subject: [PATCH 176/335] CONTRIBUTING: add a note about instrumentation versioning and depdendencies (#2851) --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9072a6a641..61f261f001 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -275,6 +275,7 @@ Below is a checklist of things to be mindful of when implementing a new instrume - Isolate sync and async test - For synchronous tests, the typical test case class is inherited from `opentelemetry.test.test_base.TestBase`. However, if you want to write asynchronous tests, the test case class should inherit also from `IsolatedAsyncioTestCase`. Adding asynchronous tests to a common test class can lead to tests passing without actually running, which can be misleading. - ex. +- All instrumentations have the same version. If you are going to develop a new instrumentation it would probably have `X.Y.dev` version and depends on `opentelemetry-instrumentation` and `opentelemetry-semantic-conventions` for the same version. That means that if you want to install your instrumentation you need to install its dependencies from this repo and the core repo also from git. ## Expectations from contributors From 02c956190d784383fa6a52f4c7a16ca9a416b3b5 Mon Sep 17 00:00:00 2001 From: Tobias Backer Dirks Date: Tue, 10 Sep 2024 17:45:06 +0300 Subject: [PATCH 177/335] feat: add ability to optionally disable internal HTTP send and receive spans (#2802) --- CHANGELOG.md | 2 + .../instrumentation/asgi/__init__.py | 174 +++++++++++------- .../tests/test_asgi_middleware.py | 24 +++ .../instrumentation/fastapi/__init__.py | 29 ++- 4 files changed, 160 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 003f8054f6..d091ddeb9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537)) +- `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi` Add ability to disable internal HTTP send and receive spans + ([#2802](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2802)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 420fd512d6..d25ca41017 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -483,7 +483,7 @@ def get_default_span_details(scope: dict) -> Tuple[str, dict]: def _collect_target_attribute( - scope: typing.Dict[str, typing.Any] + scope: typing.Dict[str, typing.Any], ) -> typing.Optional[str]: """ Returns the target path as defined by the Semantic Conventions. @@ -529,6 +529,7 @@ class OpenTelemetryMiddleware: the current globally configured one is used. meter_provider: The optional meter provider to use. If omitted the current globally configured one is used. + exclude_spans: Optionally exclude HTTP `send` and/or `receive` spans from the trace. """ # pylint: disable=too-many-branches @@ -547,6 +548,7 @@ def __init__( http_capture_headers_server_request: list[str] | None = None, http_capture_headers_server_response: list[str] | None = None, http_capture_headers_sanitize_fields: list[str] | None = None, + exclude_spans: list[typing.Literal["receive", "send"]] | None = None, ): # initialize semantic conventions opt-in if needed _OpenTelemetrySemanticConventionStability._initialize() @@ -653,6 +655,12 @@ def __init__( ) or [] ) + self.exclude_receive_span = ( + "receive" in exclude_spans if exclude_spans else False + ) + self.exclude_send_span = ( + "send" in exclude_spans if exclude_spans else False + ) # pylint: disable=too-many-statements async def __call__( @@ -796,8 +804,10 @@ async def __call__( span.end() # pylint: enable=too-many-branches - def _get_otel_receive(self, server_span_name, scope, receive): + if self.exclude_receive_span: + return receive + @wraps(receive) async def otel_receive(): with self.tracer.start_as_current_span( @@ -821,6 +831,66 @@ async def otel_receive(): return otel_receive + def _set_send_span( + self, + server_span_name, + scope, + send, + message, + status_code, + expecting_trailers, + ): + """Set send span attributes and status code.""" + with self.tracer.start_as_current_span( + " ".join((server_span_name, scope["type"], "send")) + ) as send_span: + if callable(self.client_response_hook): + self.client_response_hook(send_span, scope, message) + + if send_span.is_recording(): + if message["type"] == "http.response.start": + expecting_trailers = message.get("trailers", False) + send_span.set_attribute("asgi.event.type", message["type"]) + + if status_code: + set_status_code( + send_span, + status_code, + None, + self._sem_conv_opt_in_mode, + ) + return expecting_trailers + + def _set_server_span( + self, server_span, message, status_code, duration_attrs + ): + """Set server span attributes and status code.""" + if ( + server_span.is_recording() + and server_span.kind == trace.SpanKind.SERVER + and "headers" in message + ): + custom_response_attributes = ( + collect_custom_headers_attributes( + message, + self.http_capture_headers_sanitize_fields, + self.http_capture_headers_server_response, + normalise_response_header_name, + ) + if self.http_capture_headers_server_response + else {} + ) + if len(custom_response_attributes) > 0: + server_span.set_attributes(custom_response_attributes) + + if status_code: + set_status_code( + server_span, + status_code, + duration_attrs, + self._sem_conv_opt_in_mode, + ) + def _get_otel_send( self, server_span, @@ -834,74 +904,46 @@ def _get_otel_send( @wraps(send) async def otel_send(message: dict[str, Any]): nonlocal expecting_trailers - with self.tracer.start_as_current_span( - " ".join((server_span_name, scope["type"], "send")) - ) as send_span: - if callable(self.client_response_hook): - self.client_response_hook(send_span, scope, message) - status_code = None - if message["type"] == "http.response.start": - status_code = message["status"] - elif message["type"] == "websocket.send": - status_code = 200 - - if send_span.is_recording(): - if message["type"] == "http.response.start": - expecting_trailers = message.get("trailers", False) - send_span.set_attribute("asgi.event.type", message["type"]) - if ( - server_span.is_recording() - and server_span.kind == trace.SpanKind.SERVER - and "headers" in message - ): - custom_response_attributes = ( - collect_custom_headers_attributes( - message, - self.http_capture_headers_sanitize_fields, - self.http_capture_headers_server_response, - normalise_response_header_name, - ) - if self.http_capture_headers_server_response - else {} - ) - if len(custom_response_attributes) > 0: - server_span.set_attributes( - custom_response_attributes - ) - if status_code: - # We record metrics only once - set_status_code( - server_span, - status_code, - duration_attrs, - self._sem_conv_opt_in_mode, - ) - set_status_code( - send_span, - status_code, - None, - self._sem_conv_opt_in_mode, - ) + status_code = None + if message["type"] == "http.response.start": + status_code = message["status"] + elif message["type"] == "websocket.send": + status_code = 200 - propagator = get_global_response_propagator() - if propagator: - propagator.inject( - message, - context=set_span_in_context( - server_span, trace.context_api.Context() - ), - setter=asgi_setter, - ) + if not self.exclude_send_span: + expecting_trailers = self._set_send_span( + server_span_name, + scope, + send, + message, + status_code, + expecting_trailers, + ) - content_length = asgi_getter.get(message, "content-length") - if content_length: - try: - self.content_length_header = int(content_length[0]) - except ValueError: - pass + self._set_server_span( + server_span, message, status_code, duration_attrs + ) + + propagator = get_global_response_propagator() + if propagator: + propagator.inject( + message, + context=set_span_in_context( + server_span, trace.context_api.Context() + ), + setter=asgi_setter, + ) + + content_length = asgi_getter.get(message, "content-length") + if content_length: + try: + self.content_length_header = int(content_length[0]) + except ValueError: + pass + + await send(message) - await send(message) # pylint: disable=too-many-boolean-expressions if ( not expecting_trailers diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index a21dd626c8..a9d7897ea6 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -566,6 +566,30 @@ async def test_background_execution(self): _SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9, ) + async def test_exclude_internal_spans(self): + """Test that internal spans are excluded from the emitted spans when + the `exclude_receive_span` or `exclude_send_span` attributes are set. + """ + cases = [ + (["receive", "send"], ["GET / http receive", "GET / http send"]), + (["send"], ["GET / http send"]), + (["receive"], ["GET / http receive"]), + ([], []), + ] + for exclude_spans, excluded_spans in cases: + self.memory_exporter.clear() + app = otel_asgi.OpenTelemetryMiddleware( + simple_asgi, exclude_spans=exclude_spans + ) + self.seed_app(app) + await self.send_default_request() + await self.get_all_output() + span_list = self.memory_exporter.get_finished_spans() + self.assertTrue(span_list) + for span in span_list: + for excluded_span in excluded_spans: + self.assertNotEqual(span.name, excluded_span) + async def test_trailers(self): """Test that trailers are emitted as expected and that the server span is ended BEFORE the background task is finished.""" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 37a293764e..7e4d0aac07 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -179,7 +179,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from __future__ import annotations import logging -from typing import Collection +from typing import Collection, Literal import fastapi from starlette.routing import Match @@ -222,7 +222,7 @@ class FastAPIInstrumentor(BaseInstrumentor): @staticmethod def instrument_app( - app: fastapi.FastAPI, + app, server_request_hook: ServerRequestHook = None, client_request_hook: ClientRequestHook = None, client_response_hook: ClientResponseHook = None, @@ -232,8 +232,28 @@ def instrument_app( http_capture_headers_server_request: list[str] | None = None, http_capture_headers_server_response: list[str] | None = None, http_capture_headers_sanitize_fields: list[str] | None = None, + exclude_spans: list[Literal["receive", "send"]] | None = None, ): - """Instrument an uninstrumented FastAPI application.""" + """Instrument an uninstrumented FastAPI application. + + Args: + app: The fastapi ASGI application callable to forward requests to. + server_request_hook: Optional callback which is called with the server span and ASGI + scope object for every incoming request. + client_request_hook: Optional callback which is called with the internal span, and ASGI + scope and event which are sent as dictionaries for when the method receive is called. + client_response_hook: Optional callback which is called with the internal span, and ASGI + scope and event which are sent as dictionaries for when the method send is called. + tracer_provider: The optional tracer provider to use. If omitted + the current globally configured one is used. + meter_provider: The optional meter provider to use. If omitted + the current globally configured one is used. + excluded_urls: Optional comma delimited string of regexes to match URLs that should not be traced. + http_capture_headers_server_request: Optional list of HTTP headers to capture from the request. + http_capture_headers_server_response: Optional list of HTTP headers to capture from the response. + http_capture_headers_sanitize_fields: Optional list of HTTP headers to sanitize. + exclude_spans: Optionally exclude HTTP `send` and/or `receive` spans from the trace. + """ if not hasattr(app, "_is_instrumented_by_opentelemetry"): app._is_instrumented_by_opentelemetry = False @@ -273,6 +293,7 @@ def instrument_app( http_capture_headers_server_request=http_capture_headers_server_request, http_capture_headers_server_response=http_capture_headers_server_response, http_capture_headers_sanitize_fields=http_capture_headers_sanitize_fields, + exclude_spans=exclude_spans, ) app._is_instrumented_by_opentelemetry = True if app not in _InstrumentedFastAPI._instrumented_fastapi_apps: @@ -323,6 +344,7 @@ def _instrument(self, **kwargs): else parse_excluded_urls(_excluded_urls) ) _InstrumentedFastAPI._meter_provider = kwargs.get("meter_provider") + _InstrumentedFastAPI._exclude_spans = kwargs.get("exclude_spans") fastapi.FastAPI = _InstrumentedFastAPI def _uninstrument(self, **kwargs): @@ -373,6 +395,7 @@ def __init__(self, *args, **kwargs): http_capture_headers_server_request=_InstrumentedFastAPI._http_capture_headers_server_request, http_capture_headers_server_response=_InstrumentedFastAPI._http_capture_headers_server_response, http_capture_headers_sanitize_fields=_InstrumentedFastAPI._http_capture_headers_sanitize_fields, + exclude_spans=_InstrumentedFastAPI._exclude_spans, ) self._is_instrumented_by_opentelemetry = True _InstrumentedFastAPI._instrumented_fastapi_apps.add(self) From 6f1a17d8dd5d2f2f51cfe9d65e57cc8d16632154 Mon Sep 17 00:00:00 2001 From: Jared Tan Date: Tue, 10 Sep 2024 23:43:44 +0800 Subject: [PATCH 178/335] fix grpc supported version (#2845) --- CHANGELOG.md | 2 ++ instrumentation/README.md | 2 +- .../opentelemetry-instrumentation-grpc/pyproject.toml | 2 +- .../src/opentelemetry/instrumentation/grpc/package.py | 2 +- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d091ddeb9b..07510f643c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2814](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2814)) - `opentelemetry-instrumentation` Fix the description of `http.server.duration` and `http.server.request.duration` ([#2753](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2753)) +- `opentelemetry-instrumentation-grpc` Fix grpc supported version + ([#2845](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2845)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/README.md b/instrumentation/README.md index 22c4241bab..3558027ea9 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -21,7 +21,7 @@ | [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 4.0.0 | Yes | experimental | [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration -| [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio ~= 1.27 | No | experimental +| [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio >= 1.42.0 | No | experimental | [opentelemetry-instrumentation-httpx](./opentelemetry-instrumentation-httpx) | httpx >= 0.18.0 | No | migration | [opentelemetry-instrumentation-jinja2](./opentelemetry-instrumentation-jinja2) | jinja2 >= 2.7, < 4.0 | No | experimental | [opentelemetry-instrumentation-kafka-python](./opentelemetry-instrumentation-kafka-python) | kafka-python >= 2.0, < 3.0,kafka-python-ng >= 2.0, < 3.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index e1956aeeea..fd84d6aac0 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -33,7 +33,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "grpcio ~= 1.27", + "grpcio >= 1.42.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/package.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/package.py index 91bdeab555..66ef914bdb 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/package.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/package.py @@ -13,4 +13,4 @@ # limitations under the License. -_instruments = ("grpcio ~= 1.27",) +_instruments = ("grpcio >= 1.42.0",) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 8c4293f261..616675ee80 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -89,7 +89,7 @@ "instrumentation": "opentelemetry-instrumentation-flask==0.49b0.dev", }, { - "library": "grpcio ~= 1.27", + "library": "grpcio >= 1.42.0", "instrumentation": "opentelemetry-instrumentation-grpc==0.49b0.dev", }, { From d135f20c2984ea76c4ea4df79e0c6af4f73d295b Mon Sep 17 00:00:00 2001 From: Jeremy Voss Date: Thu, 12 Sep 2024 00:36:59 -0700 Subject: [PATCH 179/335] Fastapi auto tests (#2860) * ep test passes * cleaned ep test * Corrected mock paths. * with installed works * tests pass * Clean up * Clean up * lint * lint --- CHANGELOG.md | 3 + .../tests/test_fastapi_instrumentation.py | 58 ++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07510f643c..977f4eea8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- `opentelemetry-instrumentation-fastapi` Add autoinstrumentation mechanism tests. + ([#2860](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2860)) + ## Version 1.27.0/0.48b0 () ### Added diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 634c74af6b..b8a6ef010e 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -16,12 +16,13 @@ import unittest from timeit import default_timer -from unittest.mock import patch +from unittest.mock import Mock, patch import fastapi from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware from fastapi.responses import JSONResponse from fastapi.testclient import TestClient +from pkg_resources import DistributionNotFound, iter_entry_points import opentelemetry.instrumentation.fastapi as otel_fastapi from opentelemetry import trace @@ -34,6 +35,9 @@ _server_duration_attrs_old, ) from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware +from opentelemetry.instrumentation.auto_instrumentation._load import ( + _load_instrumentors, +) from opentelemetry.sdk.metrics.export import ( HistogramDataPoint, NumberDataPoint, @@ -1024,6 +1028,18 @@ def client_response_hook(send_span, scope, message): ) +def get_distribution_with_fastapi(*args, **kwargs): + dist = args[0] + if dist == "fastapi~=0.58": + # Value does not matter. Only whether an exception is thrown + return None + raise DistributionNotFound() + + +def get_distribution_without_fastapi(*args, **kwargs): + raise DistributionNotFound() + + class TestAutoInstrumentation(TestBaseAutoFastAPI): """Test the auto-instrumented variant @@ -1031,6 +1047,46 @@ class TestAutoInstrumentation(TestBaseAutoFastAPI): to both. """ + def test_entry_point_exists(self): + eps = iter_entry_points("opentelemetry_instrumentor") + ep = next(eps) + self.assertEqual(ep.dist.key, "opentelemetry-instrumentation-fastapi") + self.assertEqual( + ep.module_name, "opentelemetry.instrumentation.fastapi" + ) + self.assertEqual(ep.attrs, ("FastAPIInstrumentor",)) + self.assertEqual(ep.name, "fastapi") + self.assertIsNone(next(eps, None)) + + @patch("opentelemetry.instrumentation.dependencies.get_distribution") + def test_instruments_with_fastapi_installed(self, mock_get_distribution): + mock_get_distribution.side_effect = get_distribution_with_fastapi + mock_distro = Mock() + _load_instrumentors(mock_distro) + mock_get_distribution.assert_called_once_with("fastapi~=0.58") + self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 1) + args = mock_distro.load_instrumentor.call_args.args + ep = args[0] + self.assertEqual(ep.dist.key, "opentelemetry-instrumentation-fastapi") + self.assertEqual( + ep.module_name, "opentelemetry.instrumentation.fastapi" + ) + self.assertEqual(ep.attrs, ("FastAPIInstrumentor",)) + self.assertEqual(ep.name, "fastapi") + + @patch("opentelemetry.instrumentation.dependencies.get_distribution") + def test_instruments_without_fastapi_installed( + self, mock_get_distribution + ): + mock_get_distribution.side_effect = get_distribution_without_fastapi + mock_distro = Mock() + _load_instrumentors(mock_distro) + mock_get_distribution.assert_called_once_with("fastapi~=0.58") + with self.assertRaises(DistributionNotFound): + mock_get_distribution("fastapi~=0.58") + self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 0) + mock_distro.load_instrumentor.assert_not_called() + def _create_app(self): # instrumentation is handled by the instrument call resource = Resource.create({"key1": "value1", "key2": "value2"}) From bed13f513645742f58c42003196c0ac934d8c773 Mon Sep 17 00:00:00 2001 From: BryanFauble <17128019+BryanFauble@users.noreply.github.com> Date: Fri, 13 Sep 2024 06:53:13 -0700 Subject: [PATCH 180/335] Add consistent import statement for URLLibInstrumentor (#2868) * Add consistent import statement for URLLibInstrumentor * Correct code in example * One last correction to doc to create instance --- .../opentelemetry-instrumentation-urllib/README.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-urllib/README.rst b/instrumentation/opentelemetry-instrumentation-urllib/README.rst index c78e092fb4..f673fb07f9 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/README.rst +++ b/instrumentation/opentelemetry-instrumentation-urllib/README.rst @@ -29,6 +29,8 @@ The hooks can be configured as follows: .. code:: python + from opentelemetry.instrumentation.urllib import URLLibInstrumentor + # `request_obj` is an instance of urllib.request.Request def request_hook(span, request_obj): pass @@ -38,8 +40,8 @@ The hooks can be configured as follows: def response_hook(span, request_obj, response) pass - URLLibInstrumentor.instrument( - request_hook=request_hook, response_hook=response_hook) + URLLibInstrumentor().instrument( + request_hook=request_hook, response_hook=response_hook ) Exclude lists From 1a39ac80f87bcb8b9203fdd042835153dfc0df6e Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 17 Sep 2024 00:02:39 +0500 Subject: [PATCH 181/335] feat: add opentelemetry-instrumentation-aiokafka (#2082) --- .github/workflows/lint_0.yml | 18 + .github/workflows/test_1.yml | 108 +++++ CHANGELOG.md | 4 + docs-requirements.txt | 1 + docs/instrumentation/aiokafka/aiokafka.rst | 10 + instrumentation/README.md | 1 + .../LICENSE | 201 ++++++++++ .../README.rst | 22 ++ .../pyproject.toml | 49 +++ .../instrumentation/aiokafka/__init__.py | 135 +++++++ .../instrumentation/aiokafka/package.py | 16 + .../instrumentation/aiokafka/utils.py | 370 ++++++++++++++++++ .../instrumentation/aiokafka/version.py | 15 + .../test-requirements.txt | 4 + .../tests/__init__.py | 0 .../tests/test_instrumentation.py | 40 ++ .../tests/test_utils.py | 306 +++++++++++++++ .../pyproject.toml | 1 + .../instrumentation/bootstrap_gen.py | 4 + tox.ini | 17 + 20 files changed, 1322 insertions(+) create mode 100644 docs/instrumentation/aiokafka/aiokafka.rst create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/LICENSE create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/package.py create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/tests/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py create mode 100644 instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index b5d20541e5..2236dc422c 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -970,6 +970,24 @@ jobs: - name: Run tests run: tox -e lint-instrumentation-aio-pika + lint-instrumentation-aiokafka: + name: instrumentation-aiokafka + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-aiokafka + lint-instrumentation-kafka-python: name: instrumentation-kafka-python runs-on: ubuntu-latest diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index f7e71dd6b6..30ca4e67d2 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -3094,6 +3094,114 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra + py38-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiokafka -- -ra + + py39-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aiokafka -- -ra + + py310-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aiokafka -- -ra + + py311-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aiokafka -- -ra + + py312-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aiokafka -- -ra + + pypy3-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiokafka -- -ra + py38-test-instrumentation-kafka-python_ubuntu-latest: name: instrumentation-kafka-python 3.8 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 977f4eea8f..7fa1ab2ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + - `opentelemetry-instrumentation-fastapi` Add autoinstrumentation mechanism tests. ([#2860](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2860)) +- `opentelemetry-instrumentation-aiokafka` Add instrumentor and auto instrumentation support for aiokafka + ([#2082](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2082)) ## Version 1.27.0/0.48b0 () diff --git a/docs-requirements.txt b/docs-requirements.txt index 34ce74ca7a..6342594af3 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -20,6 +20,7 @@ django>=2.2 # Required by instrumentation and exporter packages aio_pika~=7.2.0 aiohttp~=3.0 +aiokafka~=0.11.0 aiopg>=0.13.0,<1.3.0 asyncpg>=0.12.0 boto~=2.0 diff --git a/docs/instrumentation/aiokafka/aiokafka.rst b/docs/instrumentation/aiokafka/aiokafka.rst new file mode 100644 index 0000000000..4ff9c57c81 --- /dev/null +++ b/docs/instrumentation/aiokafka/aiokafka.rst @@ -0,0 +1,10 @@ +.. include:: ../../../instrumentation/opentelemetry-instrumentation-aiokafka/README.rst + :end-before: References + +API +--- + +.. automodule:: opentelemetry.instrumentation.aiokafka + :members: + :undoc-members: + :show-inheritance: diff --git a/instrumentation/README.md b/instrumentation/README.md index 3558027ea9..b87bf6f844 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -4,6 +4,7 @@ | [opentelemetry-instrumentation-aio-pika](./opentelemetry-instrumentation-aio-pika) | aio_pika >= 7.2.0, < 10.0.0 | No | experimental | [opentelemetry-instrumentation-aiohttp-client](./opentelemetry-instrumentation-aiohttp-client) | aiohttp ~= 3.0 | No | migration | [opentelemetry-instrumentation-aiohttp-server](./opentelemetry-instrumentation-aiohttp-server) | aiohttp ~= 3.0 | No | experimental +| [opentelemetry-instrumentation-aiokafka](./opentelemetry-instrumentation-aiokafka) | aiokafka >= 0.8, < 1.0 | No | experimental | [opentelemetry-instrumentation-aiopg](./opentelemetry-instrumentation-aiopg) | aiopg >= 0.13.0, < 2.0.0 | No | experimental | [opentelemetry-instrumentation-asgi](./opentelemetry-instrumentation-asgi) | asgiref ~= 3.0 | Yes | migration | [opentelemetry-instrumentation-asyncio](./opentelemetry-instrumentation-asyncio) | asyncio | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/LICENSE b/instrumentation/opentelemetry-instrumentation-aiokafka/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/README.rst b/instrumentation/opentelemetry-instrumentation-aiokafka/README.rst new file mode 100644 index 0000000000..33a3645fbd --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/README.rst @@ -0,0 +1,22 @@ +OpenTelemetry aiokafka instrumentation +======================================= + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-aiokafka.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-aiokafka/ + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-aiokafka + + +References +---------- + +* `OpenTelemetry aiokafka Instrumentation `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml new file mode 100644 index 0000000000..b2c72bc397 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-aiokafka" +dynamic = ["version"] +description = "OpenTelemetry aiokafka instrumentation" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.8" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "opentelemetry-api ~= 1.27", + "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.49b0.dev", +] + +[project.optional-dependencies] +instruments = ["aiokafka >= 0.8, < 1.0"] + +[project.entry-points.opentelemetry_instrumentor] +aiokafka = "opentelemetry.instrumentation.aiokafka:AIOKafkaInstrumentor" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiokafka" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/aiokafka/version.py" + +[tool.hatch.build.targets.sdist] +include = ["/src", "/tests"] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py new file mode 100644 index 0000000000..5b2b0cd0e8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py @@ -0,0 +1,135 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Instrument aiokafka to report instrumentation-kafka produced and consumed messages + +Usage +----- + +..code:: python + + from opentelemetry.instrumentation.aiokafka import AIOKafkaInstrumentor + from aiokafka import AIOKafkaProducer, AIOKafkaConsumer + + # Instrument kafka + AIOKafkaInstrumentor().instrument() + + # report a span of type producer with the default settings + producer = AIOKafkaProducer(bootstrap_servers=['localhost:9092']) + await producer.send('my-topic', b'raw_bytes') + + # report a span of type consumer with the default settings + consumer = AIOKafkaConsumer('my-topic', group_id='my-group', bootstrap_servers=['localhost:9092']) + async for message in consumer: + # process message + +The _instrument() method accepts the following keyword args: +tracer_provider (TracerProvider) - an optional tracer provider +async_produce_hook (Callable) - a function with extra user-defined logic to be performed before sending the message +this function signature is: +def async_produce_hook(span: Span, args, kwargs) +async_consume_hook (Callable) - a function with extra user-defined logic to be performed after consuming a message +this function signature is: +def async_consume_hook(span: Span, record: kafka.record.ABCRecord, args, kwargs) +for example: + +.. code: python + from opentelemetry.instrumentation.kafka import AIOKafkaInstrumentor + from aiokafka import AIOKafkaProducer, AIOKafkaConsumer + + async def async_produce_hook(span, args, kwargs): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_async_response_hook", "some-value") + async def async_consume_hook(span, record, args, kwargs): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_consume_hook", "some-value") + + # instrument kafka with produce and consume hooks + AIOKafkaInstrumentor().instrument(async_produce_hook=async_produce_hook, async_consume_hook=async_consume_hook) + + # Using kafka as normal now will automatically generate spans, + # including user custom attributes added from the hooks + producer = AIOKafkaProducer(bootstrap_servers=['localhost:9092']) + await producer.send('my-topic', b'raw_bytes') + +API +___ +""" +from asyncio import iscoroutinefunction +from typing import Collection + +import aiokafka +from wrapt import wrap_function_wrapper + +from opentelemetry import trace +from opentelemetry.instrumentation.aiokafka.package import _instruments +from opentelemetry.instrumentation.aiokafka.utils import ( + _wrap_anext, + _wrap_send, +) +from opentelemetry.instrumentation.aiokafka.version import __version__ +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.instrumentation.utils import unwrap +from opentelemetry.semconv.schemas import Schemas + + +class AIOKafkaInstrumentor(BaseInstrumentor): + """An instrumentor for kafka module + See `BaseInstrumentor` + """ + + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs): + """Instruments the kafka module + + Args: + **kwargs: Optional arguments + ``tracer_provider``: a TracerProvider, defaults to global. + ``async_produce_hook``: a callable to be executed just before producing a message + ``async_consume_hook``: a callable to be executed just after consuming a message + """ + tracer_provider = kwargs.get("tracer_provider") + + async_produce_hook = kwargs.get("async_produce_hook") + if not iscoroutinefunction(async_produce_hook): + async_produce_hook = None + + async_consume_hook = kwargs.get("async_consume_hook") + if not iscoroutinefunction(async_consume_hook): + async_consume_hook = None + + tracer = trace.get_tracer( + __name__, + __version__, + tracer_provider=tracer_provider, + schema_url=Schemas.V1_27_0.value, + ) + + wrap_function_wrapper( + aiokafka.AIOKafkaProducer, + "send", + _wrap_send(tracer, async_produce_hook), + ) + wrap_function_wrapper( + aiokafka.AIOKafkaConsumer, + "__anext__", + _wrap_anext(tracer, async_consume_hook), + ) + + def _uninstrument(self, **kwargs): + unwrap(aiokafka.AIOKafkaProducer, "send") + unwrap(aiokafka.AIOKafkaConsumer, "__anext__") diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/package.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/package.py new file mode 100644 index 0000000000..69367d3447 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/package.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +_instruments = ("aiokafka >= 0.8, < 1.0",) diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py new file mode 100644 index 0000000000..3c54ce1500 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py @@ -0,0 +1,370 @@ +import json +from logging import getLogger +from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Union + +import aiokafka +from aiokafka import ConsumerRecord + +from opentelemetry import context, propagate, trace +from opentelemetry.context import Context +from opentelemetry.propagators import textmap +from opentelemetry.semconv._incubating.attributes import messaging_attributes +from opentelemetry.semconv.attributes import server_attributes +from opentelemetry.trace import Tracer +from opentelemetry.trace.span import Span + +_LOG = getLogger(__name__) + + +def _extract_bootstrap_servers( + client: aiokafka.AIOKafkaClient, +) -> Union[str, List[str]]: + return client._bootstrap_servers + + +def _extract_client_id(client: aiokafka.AIOKafkaClient) -> str: + return client._client_id + + +def _extract_consumer_group( + consumer: aiokafka.AIOKafkaConsumer, +) -> Optional[str]: + return consumer._group_id + + +def _extract_argument( + key: str, + position: int, + default_value: Any, + args: Tuple[Any], + kwargs: Dict[str, Any], +) -> Any: + if len(args) > position: + return args[position] + return kwargs.get(key, default_value) + + +def _extract_send_topic(args: Tuple[Any], kwargs: Dict[str, Any]) -> str: + """extract topic from `send` method arguments in AIOKafkaProducer class""" + return _extract_argument("topic", 0, "unknown", args, kwargs) + + +def _extract_send_value( + args: Tuple[Any], kwargs: Dict[str, Any] +) -> Optional[Any]: + """extract value from `send` method arguments in AIOKafkaProducer class""" + return _extract_argument("value", 1, None, args, kwargs) + + +def _extract_send_key( + args: Tuple[Any], kwargs: Dict[str, Any] +) -> Optional[Any]: + """extract key from `send` method arguments in AIOKafkaProducer class""" + return _extract_argument("key", 2, None, args, kwargs) + + +def _extract_send_headers(args: Tuple[Any], kwargs: Dict[str, Any]): + """extract headers from `send` method arguments in AIOKafkaProducer class""" + return _extract_argument("headers", 5, None, args, kwargs) + + +async def _extract_send_partition( + instance: aiokafka.AIOKafkaProducer, + args: Tuple[Any], + kwargs: Dict[str, Any], +) -> Optional[int]: + """extract partition `send` method arguments, using the `_partition` method in AIOKafkaProducer class""" + try: + topic = _extract_send_topic(args, kwargs) + key = _extract_send_key(args, kwargs) + value = _extract_send_value(args, kwargs) + partition = _extract_argument("partition", 3, None, args, kwargs) + key_bytes, value_bytes = instance._serialize(topic, key, value) + valid_types = (bytes, bytearray, memoryview, type(None)) + if ( + type(key_bytes) not in valid_types + or type(value_bytes) not in valid_types + ): + return None + + await instance.client._wait_on_metadata(topic) + + return instance._partition( + topic, partition, key, value, key_bytes, value_bytes + ) + except Exception as exception: # pylint: disable=W0703 + _LOG.debug("Unable to extract partition: %s", exception) + return None + + +ProduceHookT = Optional[Callable[[Span, Tuple, Dict], Awaitable[None]]] +ConsumeHookT = Optional[ + Callable[[Span, ConsumerRecord, Tuple, Dict], Awaitable[None]] +] + +HeadersT = List[Tuple[str, Optional[bytes]]] + + +class AIOKafkaContextGetter(textmap.Getter[HeadersT]): + def get(self, carrier: HeadersT, key: str) -> Optional[List[str]]: + if carrier is None: + return None + + for item_key, value in carrier: + if item_key == key: + if value is not None: + return [value.decode()] + return None + + def keys(self, carrier: HeadersT) -> List[str]: + if carrier is None: + return [] + return [key for (key, value) in carrier] + + +class AIOKafkaContextSetter(textmap.Setter[HeadersT]): + def set( + self, carrier: HeadersT, key: Optional[str], value: Optional[str] + ) -> None: + if carrier is None or key is None: + return + + if value is not None: + carrier.append((key, value.encode())) + else: + carrier.append((key, value)) + + +_aiokafka_getter = AIOKafkaContextGetter() +_aiokafka_setter = AIOKafkaContextSetter() + + +def _enrich_base_span( + span: Span, + *, + bootstrap_servers: Union[str, List[str]], + client_id: str, + topic: str, + partition: Optional[int], + key: Optional[Any], +) -> None: + span.set_attribute( + messaging_attributes.MESSAGING_SYSTEM, + messaging_attributes.MessagingSystemValues.KAFKA.value, + ) + span.set_attribute( + server_attributes.SERVER_ADDRESS, json.dumps(bootstrap_servers) + ) + span.set_attribute(messaging_attributes.MESSAGING_CLIENT_ID, client_id) + span.set_attribute(messaging_attributes.MESSAGING_DESTINATION_NAME, topic) + + if partition is not None: + span.set_attribute( + messaging_attributes.MESSAGING_DESTINATION_PARTITION_ID, + str(partition), + ) + + if key is not None: + span.set_attribute( + messaging_attributes.MESSAGING_KAFKA_MESSAGE_KEY, key + ) + + +def _enrich_send_span( + span: Span, + *, + bootstrap_servers: Union[str, List[str]], + client_id: str, + topic: str, + partition: Optional[int], + key: Optional[str], +) -> None: + if not span.is_recording(): + return + + _enrich_base_span( + span, + bootstrap_servers=bootstrap_servers, + client_id=client_id, + topic=topic, + partition=partition, + key=key, + ) + + span.set_attribute(messaging_attributes.MESSAGING_OPERATION_NAME, "send") + span.set_attribute( + messaging_attributes.MESSAGING_OPERATION_TYPE, + messaging_attributes.MessagingOperationTypeValues.PUBLISH.value, + ) + + +def _enrich_anext_span( + span: Span, + *, + bootstrap_servers: Union[str, List[str]], + client_id: str, + consumer_group: Optional[str], + topic: str, + partition: Optional[int], + key: Optional[str], + offset: int, +) -> None: + if not span.is_recording(): + return + + _enrich_base_span( + span, + bootstrap_servers=bootstrap_servers, + client_id=client_id, + topic=topic, + partition=partition, + key=key, + ) + + if consumer_group is not None: + span.set_attribute( + messaging_attributes.MESSAGING_CONSUMER_GROUP_NAME, consumer_group + ) + + span.set_attribute( + messaging_attributes.MESSAGING_OPERATION_NAME, "receive" + ) + span.set_attribute( + messaging_attributes.MESSAGING_OPERATION_TYPE, + messaging_attributes.MessagingOperationTypeValues.RECEIVE.value, + ) + + span.set_attribute( + messaging_attributes.MESSAGING_KAFKA_MESSAGE_OFFSET, offset + ) + + # https://stackoverflow.com/questions/65935155/identify-and-find-specific-message-in-kafka-topic + # A message within Kafka is uniquely defined by its topic name, topic partition and offset. + if partition is not None: + span.set_attribute( + messaging_attributes.MESSAGING_MESSAGE_ID, + f"{topic}.{partition}.{offset}", + ) + + +def _get_span_name(operation: str, topic: str): + return f"{topic} {operation}" + + +def _wrap_send( + tracer: Tracer, async_produce_hook: ProduceHookT +) -> Callable[..., Awaitable[None]]: + async def _traced_send( + func: Callable[..., Awaitable[None]], + instance: aiokafka.AIOKafkaProducer, + args: Tuple[Any], + kwargs: Dict[str, Any], + ) -> None: + headers = _extract_send_headers(args, kwargs) + if headers is None: + headers = [] + kwargs["headers"] = headers + + topic = _extract_send_topic(args, kwargs) + bootstrap_servers = _extract_bootstrap_servers(instance.client) + client_id = _extract_client_id(instance.client) + key = _extract_send_key(args, kwargs) + partition = await _extract_send_partition(instance, args, kwargs) + span_name = _get_span_name("send", topic) + with tracer.start_as_current_span( + span_name, kind=trace.SpanKind.PRODUCER + ) as span: + _enrich_send_span( + span, + bootstrap_servers=bootstrap_servers, + client_id=client_id, + topic=topic, + partition=partition, + key=key, + ) + propagate.inject( + headers, + context=trace.set_span_in_context(span), + setter=_aiokafka_setter, + ) + try: + if async_produce_hook is not None: + await async_produce_hook(span, args, kwargs) + except Exception as hook_exception: # pylint: disable=W0703 + _LOG.exception(hook_exception) + + return await func(*args, **kwargs) + + return _traced_send + + +async def _create_consumer_span( + tracer: Tracer, + async_consume_hook: ConsumeHookT, + record: ConsumerRecord, + extracted_context: Context, + bootstrap_servers: Union[str, List[str]], + client_id: str, + consumer_group: Optional[str], + args: Tuple[Any], + kwargs: Dict[str, Any], +): + span_name = _get_span_name("receive", record.topic) + with tracer.start_as_current_span( + span_name, + context=extracted_context, + kind=trace.SpanKind.CONSUMER, + ) as span: + new_context = trace.set_span_in_context(span, extracted_context) + token = context.attach(new_context) + _enrich_anext_span( + span, + bootstrap_servers=bootstrap_servers, + client_id=client_id, + consumer_group=consumer_group, + topic=record.topic, + partition=record.partition, + key=record.key, + offset=record.offset, + ) + try: + if async_consume_hook is not None: + await async_consume_hook(span, record, args, kwargs) + except Exception as hook_exception: # pylint: disable=W0703 + _LOG.exception(hook_exception) + context.detach(token) + + +def _wrap_anext( + tracer: Tracer, async_consume_hook: ConsumeHookT +) -> Callable[..., Awaitable[aiokafka.ConsumerRecord]]: + async def _traced_next( + func: Callable[..., Awaitable[aiokafka.ConsumerRecord]], + instance: aiokafka.AIOKafkaConsumer, + args: Tuple[Any], + kwargs: Dict[str, Any], + ) -> aiokafka.ConsumerRecord: + record = await func(*args, **kwargs) + + if record: + bootstrap_servers = _extract_bootstrap_servers(instance._client) + client_id = _extract_client_id(instance._client) + consumer_group = _extract_consumer_group(instance) + + extracted_context = propagate.extract( + record.headers, getter=_aiokafka_getter + ) + await _create_consumer_span( + tracer, + async_consume_hook, + record, + extracted_context, + bootstrap_servers, + client_id, + consumer_group, + args, + kwargs, + ) + return record + + return _traced_next diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py new file mode 100644 index 0000000000..ee5a6342e7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "0.49b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt new file mode 100644 index 0000000000..460e58e091 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt @@ -0,0 +1,4 @@ +aiokafka==0.11.0 +pytest==7.4.4 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-aiokafka diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py new file mode 100644 index 0000000000..1c4e5e3d10 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py @@ -0,0 +1,40 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from unittest import TestCase + +from aiokafka import AIOKafkaConsumer, AIOKafkaProducer +from wrapt import BoundFunctionWrapper + +from opentelemetry.instrumentation.aiokafka import AIOKafkaInstrumentor + + +class TestAIOKafka(TestCase): + def test_instrument_api(self) -> None: + instrumentation = AIOKafkaInstrumentor() + + instrumentation.instrument() + self.assertTrue( + isinstance(AIOKafkaProducer.send, BoundFunctionWrapper) + ) + self.assertTrue( + isinstance(AIOKafkaConsumer.__anext__, BoundFunctionWrapper) + ) + + instrumentation.uninstrument() + self.assertFalse( + isinstance(AIOKafkaProducer.send, BoundFunctionWrapper) + ) + self.assertFalse( + isinstance(AIOKafkaConsumer.__anext__, BoundFunctionWrapper) + ) diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py new file mode 100644 index 0000000000..b1b2792608 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py @@ -0,0 +1,306 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# pylint: disable=unnecessary-dunder-call + +from unittest import IsolatedAsyncioTestCase, mock + +from opentelemetry.instrumentation.aiokafka.utils import ( + AIOKafkaContextGetter, + AIOKafkaContextSetter, + _aiokafka_getter, + _aiokafka_setter, + _create_consumer_span, + _extract_send_partition, + _get_span_name, + _wrap_anext, + _wrap_send, +) +from opentelemetry.trace import SpanKind + + +class TestUtils(IsolatedAsyncioTestCase): + def setUp(self) -> None: + super().setUp() + self.topic_name = "test_topic" + self.args = [self.topic_name] + self.headers = [] + self.kwargs = {"partition": 0, "headers": self.headers} + + def test_context_setter(self) -> None: + context_setter = AIOKafkaContextSetter() + + carrier_list = [("key1", b"val1")] + context_setter.set(carrier_list, "key2", "val2") + self.assertTrue(("key2", "val2".encode()) in carrier_list) + + def test_context_getter(self) -> None: + context_setter = AIOKafkaContextSetter() + context_getter = AIOKafkaContextGetter() + + carrier_list = [] + context_setter.set(carrier_list, "key1", "val1") + self.assertEqual(context_getter.get(carrier_list, "key1"), ["val1"]) + self.assertEqual(["key1"], context_getter.keys(carrier_list)) + + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_bootstrap_servers" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_send_partition" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._enrich_send_span" + ) + @mock.patch("opentelemetry.trace.set_span_in_context") + @mock.patch("opentelemetry.propagate.inject") + async def test_wrap_send_with_topic_as_arg( + self, + inject: mock.MagicMock, + set_span_in_context: mock.MagicMock, + enrich_span: mock.MagicMock, + extract_send_partition: mock.MagicMock, + extract_bootstrap_servers: mock.MagicMock, + ) -> None: + await self.wrap_send_helper( + inject, + set_span_in_context, + enrich_span, + extract_send_partition, + extract_bootstrap_servers, + ) + + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_bootstrap_servers" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_send_partition" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._enrich_send_span" + ) + @mock.patch("opentelemetry.trace.set_span_in_context") + @mock.patch("opentelemetry.propagate.inject") + async def test_wrap_send_with_topic_as_kwarg( + self, + inject: mock.MagicMock, + set_span_in_context: mock.MagicMock, + enrich_span: mock.MagicMock, + extract_send_partition: mock.AsyncMock, + extract_bootstrap_servers: mock.MagicMock, + ) -> None: + self.args = [] + self.kwargs["topic"] = self.topic_name + await self.wrap_send_helper( + inject, + set_span_in_context, + enrich_span, + extract_send_partition, + extract_bootstrap_servers, + ) + + async def wrap_send_helper( + self, + inject: mock.MagicMock, + set_span_in_context: mock.MagicMock, + enrich_span: mock.MagicMock, + extract_send_partition: mock.AsyncMock, + extract_bootstrap_servers: mock.MagicMock, + ) -> None: + tracer = mock.MagicMock() + produce_hook = mock.AsyncMock() + original_send_callback = mock.AsyncMock() + kafka_producer = mock.MagicMock() + expected_span_name = _get_span_name("send", self.topic_name) + + wrapped_send = _wrap_send(tracer, produce_hook) + retval = await wrapped_send( + original_send_callback, kafka_producer, self.args, self.kwargs + ) + + extract_bootstrap_servers.assert_called_once_with( + kafka_producer.client + ) + extract_send_partition.assert_awaited_once_with( + kafka_producer, self.args, self.kwargs + ) + tracer.start_as_current_span.assert_called_once_with( + expected_span_name, kind=SpanKind.PRODUCER + ) + + span = tracer.start_as_current_span().__enter__.return_value + enrich_span.assert_called_once_with( + span, + bootstrap_servers=extract_bootstrap_servers.return_value, + client_id=kafka_producer.client._client_id, + topic=self.topic_name, + partition=extract_send_partition.return_value, + key=None, + ) + + set_span_in_context.assert_called_once_with(span) + context = set_span_in_context.return_value + inject.assert_called_once_with( + self.headers, context=context, setter=_aiokafka_setter + ) + + produce_hook.assert_awaited_once_with(span, self.args, self.kwargs) + + original_send_callback.assert_awaited_once_with( + *self.args, **self.kwargs + ) + self.assertEqual(retval, original_send_callback.return_value) + + @mock.patch("opentelemetry.propagate.extract") + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._create_consumer_span" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_bootstrap_servers" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_client_id" + ) + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._extract_consumer_group" + ) + async def test_wrap_next( + self, + extract_consumer_group: mock.MagicMock, + extract_client_id: mock.MagicMock, + extract_bootstrap_servers: mock.MagicMock, + _create_consumer_span: mock.MagicMock, + extract: mock.MagicMock, + ) -> None: + tracer = mock.MagicMock() + consume_hook = mock.AsyncMock() + original_next_callback = mock.AsyncMock() + kafka_consumer = mock.MagicMock() + + wrapped_next = _wrap_anext(tracer, consume_hook) + record = await wrapped_next( + original_next_callback, kafka_consumer, self.args, self.kwargs + ) + + extract_bootstrap_servers.assert_called_once_with( + kafka_consumer._client + ) + bootstrap_servers = extract_bootstrap_servers.return_value + + extract_client_id.assert_called_once_with(kafka_consumer._client) + client_id = extract_client_id.return_value + + extract_consumer_group.assert_called_once_with(kafka_consumer) + consumer_group = extract_consumer_group.return_value + + original_next_callback.assert_awaited_once_with( + *self.args, **self.kwargs + ) + self.assertEqual(record, original_next_callback.return_value) + + extract.assert_called_once_with( + record.headers, getter=_aiokafka_getter + ) + context = extract.return_value + + _create_consumer_span.assert_called_once_with( + tracer, + consume_hook, + record, + context, + bootstrap_servers, + client_id, + consumer_group, + self.args, + self.kwargs, + ) + + @mock.patch("opentelemetry.trace.set_span_in_context") + @mock.patch("opentelemetry.context.attach") + @mock.patch( + "opentelemetry.instrumentation.aiokafka.utils._enrich_anext_span" + ) + @mock.patch("opentelemetry.context.detach") + async def test_create_consumer_span( + self, + detach: mock.MagicMock, + enrich_span: mock.MagicMock, + attach: mock.MagicMock, + set_span_in_context: mock.MagicMock, + ) -> None: + tracer = mock.MagicMock() + consume_hook = mock.AsyncMock() + bootstrap_servers = mock.MagicMock() + extracted_context = mock.MagicMock() + record = mock.MagicMock() + client_id = mock.MagicMock() + consumer_group = mock.MagicMock() + + await _create_consumer_span( + tracer, + consume_hook, + record, + extracted_context, + bootstrap_servers, + client_id, + consumer_group, + self.args, + self.kwargs, + ) + + expected_span_name = _get_span_name("receive", record.topic) + + tracer.start_as_current_span.assert_called_once_with( + expected_span_name, + context=extracted_context, + kind=SpanKind.CONSUMER, + ) + span = tracer.start_as_current_span.return_value.__enter__() + set_span_in_context.assert_called_once_with(span, extracted_context) + attach.assert_called_once_with(set_span_in_context.return_value) + + enrich_span.assert_called_once_with( + span, + bootstrap_servers=bootstrap_servers, + client_id=client_id, + consumer_group=consumer_group, + topic=record.topic, + partition=record.partition, + key=record.key, + offset=record.offset, + ) + consume_hook.assert_awaited_once_with( + span, record, self.args, self.kwargs + ) + detach.assert_called_once_with(attach.return_value) + + async def test_kafka_properties_extractor(self): + aiokafka_instance_mock = mock.Mock() + aiokafka_instance_mock._serialize.return_value = None, None + aiokafka_instance_mock._partition.return_value = "partition" + aiokafka_instance_mock.client._wait_on_metadata = mock.AsyncMock() + assert ( + await _extract_send_partition( + aiokafka_instance_mock, self.args, self.kwargs + ) + == "partition" + ) + aiokafka_instance_mock.client._wait_on_metadata.side_effect = ( + Exception("mocked error") + ) + assert ( + await _extract_send_partition( + aiokafka_instance_mock, self.args, self.kwargs + ) + is None + ) diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 9c40f9c2a3..300895c1e0 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -32,6 +32,7 @@ dependencies = [ "opentelemetry-instrumentation-aio-pika==0.49b0.dev", "opentelemetry-instrumentation-aiohttp-client==0.49b0.dev", "opentelemetry-instrumentation-aiohttp-server==0.49b0.dev", + "opentelemetry-instrumentation-aiokafka==0.49b0.dev", "opentelemetry-instrumentation-aiopg==0.49b0.dev", "opentelemetry-instrumentation-asgi==0.49b0.dev", "opentelemetry-instrumentation-asyncio==0.49b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 616675ee80..cc9af1de80 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -28,6 +28,10 @@ "library": "aiohttp ~= 3.0", "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.49b0.dev", }, + { + "library": "aiokafka >= 0.8, < 1.0", + "instrumentation": "opentelemetry-instrumentation-aiokafka==0.49b0.dev", + }, { "library": "aiopg >= 0.13.0, < 2.0.0", "instrumentation": "opentelemetry-instrumentation-aiopg==0.49b0.dev", diff --git a/tox.ini b/tox.ini index 600929a6ec..f7e4ce55b3 100644 --- a/tox.ini +++ b/tox.ini @@ -342,6 +342,11 @@ envlist = pypy3-test-instrumentation-aio-pika-{0,1,2,3} lint-instrumentation-aio-pika + ; opentelemetry-instrumentation-aiokafka + py3{8,9,10,11,12}-test-instrumentation-aiokafka + pypy3-test-instrumentation-aiokafka + lint-instrumentation-aiokafka + ; opentelemetry-instrumentation-kafka-python py3{8,9,10,11}-test-instrumentation-kafka-python py3{8,9,10,11,12}-test-instrumentation-kafka-pythonng @@ -436,6 +441,11 @@ commands_pre = aio-pika-3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt lint-instrumentation-aio-pika: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt + aiokafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + aiokafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + aiokafka: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + aiokafka: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt + kafka-python: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api kafka-python: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions kafka-python: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -930,6 +940,12 @@ commands = lint-instrumentation-jinja2: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 lint-instrumentation-jinja2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-jinja2" + test-instrumentation-aiokafka: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka/tests {posargs} + lint-instrumentation-aiokafka: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka + lint-instrumentation-aiokafka: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka + lint-instrumentation-aiokafka: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka + lint-instrumentation-aiokafka: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiokafka" + test-instrumentation-kafka-python: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/tests {posargs} lint-instrumentation-kafka-python: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python lint-instrumentation-kafka-python: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python @@ -1277,6 +1293,7 @@ commands_pre = -e {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg \ -e {toxinidir}/instrumentation/opentelemetry-instrumentation-celery \ -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pika \ + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka \ -e {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python \ -e {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka \ -e {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi \ From 08def3e40a72a03afb16f3a6b492663de5252469 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 17 Sep 2024 01:38:24 -0700 Subject: [PATCH 182/335] Update pyproject.toml (#2873) Co-authored-by: Riccardo Magliocchetti --- opentelemetry-instrumentation/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index edaf400419..866b9b5008 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.4", + "opentelemetry-semantic-conventions >= 0.48b0", "setuptools >= 16.0", "wrapt >= 1.0.0, < 2.0.0", ] From 97c3664fd72681348293caa23e1e96d47934ef07 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 19 Sep 2024 10:00:22 +0200 Subject: [PATCH 183/335] Fix public-symbols-check workflow generation (#2876) Consider only pull request events when running public-symbols-check. --- .../src/generate_workflows_lib/misc.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index 2b0735b432..87f726b587 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -28,7 +28,7 @@ jobs: {%- if job_data == "public-symbols-check" %} if: | !contains(github.event.pull_request.labels.*.name, 'Approve Public API check') - && github.actor != 'opentelemetrybot' + && github.actor != 'opentelemetrybot' && github.event_name == 'pull_request' {%- endif %} steps: - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} From 6fcfbd67b85e0139147b3273da97c30c4a3970a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 23 Sep 2024 04:44:07 -0300 Subject: [PATCH 184/335] tests: fix docker-tests mssql (#2878) * try new image * try new image with new pyodbc verrsion --- tests/opentelemetry-docker-tests/tests/docker-compose.yml | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/opentelemetry-docker-tests/tests/docker-compose.yml b/tests/opentelemetry-docker-tests/tests/docker-compose.yml index 2f89e3388e..59f0e42d3d 100644 --- a/tests/opentelemetry-docker-tests/tests/docker-compose.yml +++ b/tests/opentelemetry-docker-tests/tests/docker-compose.yml @@ -51,7 +51,7 @@ services: - "14268:14268" - "9411:9411" otmssql: - image: mcr.microsoft.com/mssql/server:2017-CU23-ubuntu-16.04 + image: mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 ports: - "1433:1433" environment: diff --git a/tox.ini b/tox.ini index f7e4ce55b3..976e5968b0 100644 --- a/tox.ini +++ b/tox.ini @@ -1257,7 +1257,7 @@ deps = PyMySQL==0.10.1 PyNaCl==1.5.0 # prerequisite: install unixodbc - pyodbc==4.0.39 + pyodbc==5.0.1 pyrsistent==0.20.0 pytest==8.0.2 pytest-celery==0.0.0 From 41b64539d01b79927deb2aee1388d61021658afc Mon Sep 17 00:00:00 2001 From: heidi229 Date: Tue, 24 Sep 2024 01:09:06 +0800 Subject: [PATCH 185/335] update editable install link in readme.md (#2881) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a2aaf4f8a..a04c4b7c7b 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ pip install opentelemetry-instrumentation-{integration} To install the development versions of these packages instead, clone or fork this repo and do an [editable -install](https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs): +install](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs): ```sh pip install -e ./instrumentation/opentelemetry-instrumentation-{integration} From 3deb6b9db65218d23aded29a0aa4e0374d56081d Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 23 Sep 2024 22:56:37 +0200 Subject: [PATCH 186/335] opentelemetry-instrumentation-flask: a bit more room on metrics tests (#2884) --- .../tests/test_programmatic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 4458daae21..e6bc8202df 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -520,7 +520,7 @@ def test_flask_metrics_new_semconv(self): if isinstance(point, HistogramDataPoint): self.assertEqual(point.count, 3) self.assertAlmostEqual( - duration_s, point.sum, places=2 + duration_s, point.sum, places=1 ) histogram_data_point_seen = True if isinstance(point, NumberDataPoint): From a084c2c7df030e5c9284a50bff1faced4adc36ce Mon Sep 17 00:00:00 2001 From: Rocky Ken <119533257+rocky-ken@users.noreply.github.com> Date: Wed, 25 Sep 2024 08:19:20 -0700 Subject: [PATCH 187/335] Add fallback decoding for asgi headers (#2837) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add latin-1 fallback decoding for asgi headers * Add comment for ASGI encoding spec and change to unicode_escape * add unit test for non-utf8 header decoding * add changelog * revert lint * code review changes * Fix changelog * Add ASGIGetter test --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../instrumentation/asgi/__init__.py | 20 ++++++++++++---- .../tests/test_asgi_custom_headers.py | 24 +++++++++++++++++-- .../tests/test_getter.py | 10 ++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fa1ab2ba3..a060517cdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537)) - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi` Add ability to disable internal HTTP send and receive spans ([#2802](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2802)) +- `opentelemetry-instrumentation-asgi` Add fallback decoding for ASGI headers + ([#2837](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2837)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index d25ca41017..bc45eacaa4 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -284,9 +284,9 @@ def get( # ASGI header keys are in lower case key = key.lower() decoded = [ - _value.decode("utf8") + _decode_header_item(_value) for (_key, _value) in headers - if _key.decode("utf8").lower() == key + if _decode_header_item(_key).lower() == key ] if not decoded: return None @@ -294,7 +294,7 @@ def get( def keys(self, carrier: dict) -> typing.List[str]: headers = carrier.get("headers") or [] - return [_key.decode("utf8") for (_key, _value) in headers] + return [_decode_header_item(_key) for (_key, _value) in headers] asgi_getter = ASGIGetter() @@ -410,7 +410,9 @@ def collect_custom_headers_attributes( if raw_headers: for key, value in raw_headers: # Decode headers before processing. - headers[key.decode()].append(value.decode()) + headers[_decode_header_item(key)].append( + _decode_header_item(value) + ) return sanitize.sanitize_header_values( headers, @@ -979,3 +981,13 @@ def _parse_active_request_count_attrs( _server_active_requests_count_attrs_new, sem_conv_opt_in_mode, ) + + +def _decode_header_item(value): + try: + return value.decode("utf-8") + except ValueError: + # ASGI header encoding specs, see: + # - https://asgi.readthedocs.io/en/latest/specs/www.html#wsgi-encoding-differences (see: WSGI encoding differences) + # - https://docs.python.org/3/library/codecs.html#text-encodings (see: Text Encodings) + return value.decode("unicode_escape") diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py index f6cb05fbda..1b191e30e7 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_custom_headers.py @@ -48,6 +48,14 @@ async def http_app_with_custom_headers(scope, receive, send): b"my-custom-regex-value-3,my-custom-regex-value-4", ), (b"my-secret-header", b"my-secret-value"), + ( + b"non-utf8-header", + b"Moto Z\xb2", + ), + ( + b"Moto-Z\xb2-non-utf8-header-key", + b"Moto Z\xb2", + ), ], } ) @@ -130,6 +138,14 @@ async def test_http_custom_request_headers_in_span_attributes(self): (b"Regex-Test-Header-1", b"Regex Test Value 1"), (b"regex-test-header-2", b"RegexTestValue2,RegexTestValue3"), (b"My-Secret-Header", b"My Secret Value"), + ( + b"non-utf8-header", + b"Moto Z\xb2", + ), + ( + b"Moto-Z\xb2-non-utf8-header-key", + b"Moto Z\xb2", + ), ] ) self.seed_app(self.app) @@ -147,6 +163,8 @@ async def test_http_custom_request_headers_in_span_attributes(self): "http.request.header.regex_test_header_2": ( "RegexTestValue2,RegexTestValue3", ), + "http.request.header.non_utf8_header": ("Moto Z²",), + "http.request.header.moto_z²_non_utf8_header_key": ("Moto Z²",), "http.request.header.my_secret_header": ("[REDACTED]",), } for span in span_list: @@ -223,6 +241,8 @@ async def test_http_custom_response_headers_in_span_attributes(self): "my-custom-regex-value-3,my-custom-regex-value-4", ), "http.response.header.my_secret_header": ("[REDACTED]",), + "http.response.header.non_utf8_header": ("Moto Z²",), + "http.response.header.moto_z²_non_utf8_header_key": ("Moto Z²",), } for span in span_list: if span.kind == SpanKind.SERVER: @@ -418,8 +438,8 @@ async def test_websocket_custom_response_headers_not_in_span_attributes( SANITIZE_FIELDS_TEST_VALUE = ".*my-secret.*" -SERVER_REQUEST_TEST_VALUE = "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*" -SERVER_RESPONSE_TEST_VALUE = "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*" +SERVER_REQUEST_TEST_VALUE = "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*,non-utf8-header,Moto-Z²-non-utf8-header-key" +SERVER_RESPONSE_TEST_VALUE = "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*,non-utf8-header,Moto-Z²-non-utf8-header-key" class TestCustomHeadersEnv(TestCustomHeaders): diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py index 26bb652b50..3f76e0e5ce 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py @@ -69,3 +69,13 @@ def test_keys(self): expected_val, "Should be equal", ) + + def test_non_utf8_headers(self): + getter = ASGIGetter() + carrier = {"headers": [(b"test-key", b"Moto Z\xb2")]} + expected_val = ["Moto Z²"] + self.assertEqual( + getter.get(carrier, "test-key"), + expected_val, + "Should be equal", + ) From f8bb28928cccdb1236a9aab1dec9cb0179cbb9be Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Thu, 26 Sep 2024 08:52:02 +0200 Subject: [PATCH 188/335] Update test requirements for work with Python 3.13 (#2887) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added deb to make cassandra tests work with python 3.13 * Bumped cffi to work with Python 3.13 * Fixed some test-requirements for Python 3.13 * Updated typing_extensions everywhere --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 2 +- .../test-requirements.txt | 4 ++-- .../test-requirements.txt | 3 ++- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements.txt | 8 ++++---- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-4.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 4 ++-- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 8 ++++---- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- opentelemetry-distro/test-requirements.txt | 2 +- opentelemetry-instrumentation/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-sdk-extension-aws/test-requirements.txt | 2 +- tox.ini | 2 +- util/opentelemetry-util-http/test-requirements.txt | 2 +- 81 files changed, 91 insertions(+), 90 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 5836dc9764..318e1e68d5 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -16,7 +16,7 @@ pytest==7.4.4 python-snappy==0.7.1 requests==2.32.3 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index 0ef562821f..a63c91d0d8 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -12,7 +12,7 @@ Pygments==2.17.2 pytest==7.4.4 rich==13.7.1 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e exporter/opentelemetry-exporter-richconsole diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index de853e16c9..26c7046817 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -12,7 +12,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 yarl==1.9.4 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index dbfb89fe82..fac907831a 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -12,7 +12,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 yarl==1.9.4 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 6a95bd69f0..ad807173e8 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -12,7 +12,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 yarl==1.9.4 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index 82e742a1f4..766cc6cf86 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -12,7 +12,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 yarl==1.9.4 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index dee4736133..f4da0edc25 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -23,7 +23,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 requests==2.32.3 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==2.2.2 Werkzeug==3.0.3 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index e6dff52db9..d84eccb649 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -15,7 +15,7 @@ pytest==7.4.4 pytest-aiohttp==1.0.5 pytest-asyncio==0.23.5 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 yarl==1.9.4 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 1443104081..df527586f7 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -10,7 +10,7 @@ psycopg2-binary==2.9.9 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index 18a11500e1..de88049226 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index 7f20d1497c..190e1cbe02 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -8,7 +8,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 pytest-asyncio==0.23.5 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index 60cef50a7a..bb41329e66 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -9,7 +9,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index 8d9fe19483..a80527dd36 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index fe6467d1c4..bb56100ecb 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -3,7 +3,7 @@ boto==2.49.0 boto3==1.34.44 botocore==1.34.44 certifi==2024.7.4 -cffi==1.16.0 +cffi==1.17.0 charset-normalizer==3.3.2 cryptography==42.0.5 Deprecated==1.2.14 @@ -28,7 +28,7 @@ responses==0.25.0 s3transfer==0.10.0 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==1.26.19 Werkzeug==2.3.8 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index d8a9c38315..dfa17c79a7 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -13,7 +13,7 @@ python-dateutil==2.8.2 s3transfer==0.10.0 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==1.26.19 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index a89fdf2e30..f0ceb9f467 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -3,7 +3,7 @@ aws-xray-sdk==2.12.1 boto3==1.28.80 botocore==1.31.80 certifi==2024.7.4 -cffi==1.16.0 +cffi==1.17.0 charset-normalizer==3.3.2 cryptography==42.0.5 Deprecated==1.2.14 @@ -28,7 +28,7 @@ responses==0.25.0 s3transfer==0.7.0 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==1.26.19 Werkzeug==3.0.3 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index 189b2f65d0..25bf51f2a5 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -1,5 +1,6 @@ asgiref==3.8.1 cassandra-driver==3.29.0 +pyasyncore==1.0.4 # for python 3.13 (should removed when cassandra-driver replaces asyncore with recommended asyncio) click==8.1.7 Deprecated==1.2.14 geomet==0.2.1.post1 @@ -13,7 +14,7 @@ PyYAML==6.0.1 scylla-driver==3.26.6 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index fcf838fc32..1e018aae6e 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -19,7 +19,7 @@ pytest==7.4.4 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 tzdata==2024.1 vine==5.1.0 wcwidth==0.2.13 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 76b2f03d12..c7d494aceb 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -18,7 +18,7 @@ pytest==7.4.4 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 tzdata==2024.1 vine==5.1.0 wcwidth==0.2.13 diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index f78f498620..7f389a12af 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index f76b488d90..1275616d45 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index 9d7ee964fe..6c1b8337a4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -10,7 +10,7 @@ pytest==7.4.4 pytz==2024.1 sqlparse==0.5.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index 9c21d2dfd4..357fd273f5 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -10,7 +10,7 @@ pytest==7.4.4 pytz==2024.1 sqlparse==0.5.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index d3a55aae34..1d15b1336b 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -10,7 +10,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 sqlparse==0.5.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index 89923379d3..fa483e5ade 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -9,7 +9,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 sqlparse==0.5.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index 55eabe1ef5..977a440c85 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -11,7 +11,7 @@ pytest==7.4.4 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==1.26.19 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index 2fab7287ad..44451736c8 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -11,7 +11,7 @@ pytest==7.4.4 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==1.26.19 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index 5f2ccd41ac..a02a9c0270 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -12,7 +12,7 @@ pytest==7.4.4 python-dateutil==2.8.2 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index 6967c57b6d..11a84eef70 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -10,7 +10,7 @@ pytest==7.4.4 python-mimeparse==1.6.0 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index e535925b14..9d646f3bbb 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index 30d21e2773..d2a921eb87 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 927e68f94e..0417301559 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -1,4 +1,4 @@ -annotated-types==0.6.0 +annotated-types==0.7.0 anyio==4.3.0 asgiref==3.8.1 certifi==2024.7.4 @@ -15,14 +15,14 @@ iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 -pydantic==2.6.2 -pydantic_core==2.16.3 +pydantic==2.8.2 +pydantic_core==2.20.1 pytest==7.4.4 requests==2.32.3 sniffio==1.3.0 starlette==0.36.3 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index 0bd176848d..e6fa669267 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -12,7 +12,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 Werkzeug==2.3.8 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index d73ab497b5..ecd3f680d8 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -12,7 +12,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 Werkzeug==2.3.8 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 299a347d66..da044a29e9 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -13,7 +13,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 Werkzeug==3.0.3 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt index 83ec6e8e70..cdea5fca4b 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt @@ -9,7 +9,7 @@ protobuf==3.20.3 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index d77d67148a..9b2d088da3 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -9,7 +9,7 @@ protobuf==3.20.3 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index 28b475a3a4..34eac9d10c 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -17,7 +17,7 @@ respx==0.17.1 rfc3986==1.5.0 sniffio==1.3.1 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index 42c032a546..93b4d024cb 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -16,7 +16,7 @@ pytest==7.4.4 respx==0.20.2 sniffio==1.3.1 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index 59eabe6997..c7a30b8eb5 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -9,7 +9,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index 6582cf875b..a042ce833e 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index c0d2f044c8..600d066cc1 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt index bf93434850..22e61d9df3 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index 8c3ed72f35..3dfa1b161d 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index e06bc0b395..871d4feac1 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index 8928f655c8..b1c9e9094f 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index 42bbac77d9..93ea09ca15 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -9,7 +9,7 @@ psycopg==3.1.18 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index 1f7fb59f2d..096d31599a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -8,7 +8,7 @@ psycopg==3.1.18 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index aa98fa93d0..5ae59dc5ea 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -8,7 +8,7 @@ psycopg2==2.9.9 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index 2c6e0e2749..25e0f03bd6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -9,7 +9,7 @@ pymemcache==1.3.5 pytest==7.4.4 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index 36db8d4416..3005dc7aa8 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -9,7 +9,7 @@ pymemcache==2.2.2 pytest==7.4.4 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index 3e0359f731..4c259345c6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -9,7 +9,7 @@ pymemcache==3.4.1 pytest==7.4.4 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index 916c9c9c3a..b0e2147639 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -9,7 +9,7 @@ pymemcache==3.4.2 pytest==7.4.4 six==1.16.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index e90a138ff8..36d0164961 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -8,7 +8,7 @@ py-cpuinfo==9.0.0 pymemcache==4.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index 6c8de553b6..a9319d5fdb 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -9,7 +9,7 @@ py-cpuinfo==9.0.0 pymongo==4.6.3 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index 7ad69f2b81..b1496da4e6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -8,7 +8,7 @@ py-cpuinfo==9.0.0 PyMySQL==1.1.1 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 6f33f33449..423838f23e 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -13,7 +13,7 @@ pyramid==2.0.2 pytest==7.4.4 tomli==2.0.1 translationstring==1.4 -typing_extensions==4.9.0 +typing_extensions==4.12.2 venusian==3.1.0 WebOb==1.8.8 Werkzeug==3.0.3 diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 7b8d8459b7..4690006ef1 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -10,7 +10,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 redis==5.0.1 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index b850e46f9f..a299e145a1 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -12,7 +12,7 @@ pytz==2024.1 remoulade==3.2.0 six==1.16.0 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 9f40c6d5b2..a201206f0f 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -12,7 +12,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 requests==2.32.3 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index 45992bc2e1..cccdc3cb63 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -1,5 +1,5 @@ asgiref==3.8.1 -cffi==1.15.1 +cffi==1.17.0 Deprecated==1.2.14 importlib-metadata==6.11.0 iniconfig==2.0.0 @@ -9,7 +9,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 SQLAlchemy==1.1.18 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index eb1ee371b7..b275f4e30e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -10,7 +10,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 SQLAlchemy==1.4.51 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index e260861814..2469d354d3 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index d81a15a40c..7f46b46981 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -18,7 +18,7 @@ requests==2.32.3 sniffio==1.3.0 starlette==0.13.8 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index 76f2f2a4e7..710e4bdf7f 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -8,7 +8,7 @@ psutil==6.0.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index 2d13857e9e..84c3bb4d29 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 236c45f87b..209c07e523 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -19,7 +19,7 @@ pytest==7.4.4 requests==2.32.3 tomli==2.0.1 tornado==6.4.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 urllib3==2.2.2 Werkzeug==3.0.3 wrapt==1.16.0 diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index 31b044a2f3..4ec6d195bf 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -1,5 +1,5 @@ aiosqlite==0.17.0 -annotated-types==0.6.0 +annotated-types==0.7.0 asgiref==3.8.1 Deprecated==1.2.14 importlib-metadata==6.11.0 @@ -8,14 +8,14 @@ iso8601==1.1.0 packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 -pydantic==2.6.2 -pydantic_core==2.16.3 +pydantic==2.8.2 +pydantic_core==2.20.1 pypika-tortoise==0.1.6 pytest==7.4.4 pytz==2024.1 tomli==2.0.1 tortoise-orm==0.20.0 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index 06bc8322dc..998ca77f6a 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index e7392b0c31..ad29eb1263 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==1.26.19 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 21cb3acbe6..48406b222d 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -8,7 +8,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index d63bd5a637..acabba1abf 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.9.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index 050054c39b..4f63e9e7b6 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index 31f1ef76ab..24a5a56daf 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index 4587d87629..8f5b428ba4 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -12,7 +12,7 @@ pytest==7.4.4 pytest-benchmark==4.0.0 requests==2.32.3 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index b556c4f0cc..4a97065065 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e propagator/opentelemetry-propagator-ot-trace diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements.txt b/resource/opentelemetry-resource-detector-azure/test-requirements.txt index 2b29359fbb..fe04c99490 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements.txt @@ -6,7 +6,7 @@ packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/resource/opentelemetry-resource-detector-container/test-requirements.txt b/resource/opentelemetry-resource-detector-container/test-requirements.txt index f7b5b71fcf..7cf0d49001 100644 --- a/resource/opentelemetry-resource-detector-container/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-container/test-requirements.txt @@ -7,7 +7,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e resource/opentelemetry-resource-detector-container diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt index 1fa968a8b3..3b44b54a61 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt @@ -8,7 +8,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 -e sdk-extension/opentelemetry-sdk-extension-aws diff --git a/tox.ini b/tox.ini index 976e5968b0..e0a5a71131 100644 --- a/tox.ini +++ b/tox.ini @@ -1272,7 +1272,7 @@ deps = SQLAlchemy==1.4.52 texttable==1.7.0 tomli==2.0.1 - typing_extensions==4.10.0 + typing_extensions==4.12.2 tzdata==2024.1 urllib3==1.26.19 vine==5.1.0 diff --git a/util/opentelemetry-util-http/test-requirements.txt b/util/opentelemetry-util-http/test-requirements.txt index 1769daa094..7c71ae2ef3 100644 --- a/util/opentelemetry-util-http/test-requirements.txt +++ b/util/opentelemetry-util-http/test-requirements.txt @@ -7,5 +7,5 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 -typing_extensions==4.10.0 +typing_extensions==4.12.2 -e opentelemetry-instrumentation From d52f42fb7f36c5448395f4cf842523ee9f3e01c9 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 26 Sep 2024 18:00:31 +0500 Subject: [PATCH 189/335] feat(opentelemetry-instrumentation-aiokafka): wrap getone instead of anext, add tests (#2874) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add tests * add to CHANGELOG * add tests for baggage * wrap getone instead of __anext__ * split sync and async tests (fix review) * add dimastbk to component_owners.yml for aiokafka * Update CHANGELOG.md --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/component_owners.yml | 3 + CHANGELOG.md | 6 + .../instrumentation/aiokafka/__init__.py | 8 +- .../instrumentation/aiokafka/utils.py | 2 +- .../tests/test_instrumentation.py | 290 +++++++++++++++++- .../tests/test_utils.py | 4 +- tox.ini | 1 + 7 files changed, 302 insertions(+), 12 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index e3ca06b450..dcc1013476 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -61,5 +61,8 @@ components: instrumentation/opentelemetry-instrumentation-psycopg: - federicobond + instrumentation/opentelemetry-instrumentation-aiokafka: + - dimastbk + processor/opentelemetry-processor-baggage: - codeboten diff --git a/CHANGELOG.md b/CHANGELOG.md index a060517cdf..30440c2dce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aiokafka` Add instrumentor and auto instrumentation support for aiokafka ([#2082](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2082)) + +### Fixed + +- `opentelemetry-instrumentation-aiokafka` Wrap `AIOKafkaConsumer.getone()` instead of `AIOKafkaConsumer.__anext__` + ([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874)) + ## Version 1.27.0/0.48b0 () ### Added diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py index 5b2b0cd0e8..7d994be622 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py @@ -76,7 +76,7 @@ async def async_consume_hook(span, record, args, kwargs): from opentelemetry import trace from opentelemetry.instrumentation.aiokafka.package import _instruments from opentelemetry.instrumentation.aiokafka.utils import ( - _wrap_anext, + _wrap_getone, _wrap_send, ) from opentelemetry.instrumentation.aiokafka.version import __version__ @@ -126,10 +126,10 @@ def _instrument(self, **kwargs): ) wrap_function_wrapper( aiokafka.AIOKafkaConsumer, - "__anext__", - _wrap_anext(tracer, async_consume_hook), + "getone", + _wrap_getone(tracer, async_consume_hook), ) def _uninstrument(self, **kwargs): unwrap(aiokafka.AIOKafkaProducer, "send") - unwrap(aiokafka.AIOKafkaConsumer, "__anext__") + unwrap(aiokafka.AIOKafkaConsumer, "getone") diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py index 3c54ce1500..cae0d97717 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py @@ -335,7 +335,7 @@ async def _create_consumer_span( context.detach(token) -def _wrap_anext( +def _wrap_getone( tracer: Tracer, async_consume_hook: ConsumeHookT ) -> Callable[..., Awaitable[aiokafka.ConsumerRecord]]: async def _traced_next( diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py index 1c4e5e3d10..8211566239 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py @@ -11,15 +11,29 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from unittest import TestCase -from aiokafka import AIOKafkaConsumer, AIOKafkaProducer +import uuid +from typing import Any, List, Sequence, Tuple +from unittest import IsolatedAsyncioTestCase, TestCase, mock + +from aiokafka import ( + AIOKafkaConsumer, + AIOKafkaProducer, + ConsumerRecord, + TopicPartition, +) from wrapt import BoundFunctionWrapper +from opentelemetry import baggage, context from opentelemetry.instrumentation.aiokafka import AIOKafkaInstrumentor +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.semconv._incubating.attributes import messaging_attributes +from opentelemetry.semconv.attributes import server_attributes +from opentelemetry.test.test_base import TestBase +from opentelemetry.trace import SpanKind, format_trace_id, set_span_in_context -class TestAIOKafka(TestCase): +class TestAIOKafkaInstrumentor(TestCase): def test_instrument_api(self) -> None: instrumentation = AIOKafkaInstrumentor() @@ -28,7 +42,7 @@ def test_instrument_api(self) -> None: isinstance(AIOKafkaProducer.send, BoundFunctionWrapper) ) self.assertTrue( - isinstance(AIOKafkaConsumer.__anext__, BoundFunctionWrapper) + isinstance(AIOKafkaConsumer.getone, BoundFunctionWrapper) ) instrumentation.uninstrument() @@ -36,5 +50,271 @@ def test_instrument_api(self) -> None: isinstance(AIOKafkaProducer.send, BoundFunctionWrapper) ) self.assertFalse( - isinstance(AIOKafkaConsumer.__anext__, BoundFunctionWrapper) + isinstance(AIOKafkaConsumer.getone, BoundFunctionWrapper) + ) + + +class TestAIOKafkaInstrumentation(TestBase, IsolatedAsyncioTestCase): + @staticmethod + def consumer_record_factory( + number: int, headers: Tuple[Tuple[str, bytes], ...] + ) -> ConsumerRecord: + return ConsumerRecord( + f"topic_{number}", + number, + number, + number, + number, + f"key_{number}".encode(), + f"value_{number}".encode(), + None, + number, + number, + headers=headers, + ) + + @staticmethod + async def consumer_factory(**consumer_kwargs: Any) -> AIOKafkaConsumer: + consumer = AIOKafkaConsumer(**consumer_kwargs) + + consumer._client.bootstrap = mock.AsyncMock() + consumer._client._wait_on_metadata = mock.AsyncMock() + + await consumer.start() + + consumer._fetcher.next_record = mock.AsyncMock() + + return consumer + + @staticmethod + async def producer_factory() -> AIOKafkaProducer: + producer = AIOKafkaProducer(api_version="1.0") + + producer.client._wait_on_metadata = mock.AsyncMock() + producer.client.bootstrap = mock.AsyncMock() + producer._message_accumulator.add_message = mock.AsyncMock() + producer._sender.start = mock.AsyncMock() + producer._partition = mock.Mock(return_value=1) + + await producer.start() + + return producer + + async def test_getone(self) -> None: + AIOKafkaInstrumentor().uninstrument() + AIOKafkaInstrumentor().instrument(tracer_provider=self.tracer_provider) + + client_id = str(uuid.uuid4()) + group_id = str(uuid.uuid4()) + consumer = await self.consumer_factory( + client_id=client_id, group_id=group_id + ) + next_record_mock: mock.AsyncMock = consumer._fetcher.next_record + + expected_spans = [ + { + "name": "topic_1 receive", + "kind": SpanKind.CONSUMER, + "attributes": { + messaging_attributes.MESSAGING_SYSTEM: messaging_attributes.MessagingSystemValues.KAFKA.value, + server_attributes.SERVER_ADDRESS: '"localhost"', + messaging_attributes.MESSAGING_CLIENT_ID: client_id, + messaging_attributes.MESSAGING_DESTINATION_NAME: "topic_1", + messaging_attributes.MESSAGING_DESTINATION_PARTITION_ID: "1", + messaging_attributes.MESSAGING_KAFKA_MESSAGE_KEY: "key_1", + messaging_attributes.MESSAGING_CONSUMER_GROUP_NAME: group_id, + messaging_attributes.MESSAGING_OPERATION_NAME: "receive", + messaging_attributes.MESSAGING_OPERATION_TYPE: messaging_attributes.MessagingOperationTypeValues.RECEIVE.value, + messaging_attributes.MESSAGING_KAFKA_MESSAGE_OFFSET: 1, + messaging_attributes.MESSAGING_MESSAGE_ID: "topic_1.1.1", + }, + }, + { + "name": "topic_2 receive", + "kind": SpanKind.CONSUMER, + "attributes": { + messaging_attributes.MESSAGING_SYSTEM: messaging_attributes.MessagingSystemValues.KAFKA.value, + server_attributes.SERVER_ADDRESS: '"localhost"', + messaging_attributes.MESSAGING_CLIENT_ID: client_id, + messaging_attributes.MESSAGING_DESTINATION_NAME: "topic_2", + messaging_attributes.MESSAGING_DESTINATION_PARTITION_ID: "2", + messaging_attributes.MESSAGING_KAFKA_MESSAGE_KEY: "key_2", + messaging_attributes.MESSAGING_CONSUMER_GROUP_NAME: group_id, + messaging_attributes.MESSAGING_OPERATION_NAME: "receive", + messaging_attributes.MESSAGING_OPERATION_TYPE: messaging_attributes.MessagingOperationTypeValues.RECEIVE.value, + messaging_attributes.MESSAGING_KAFKA_MESSAGE_OFFSET: 2, + messaging_attributes.MESSAGING_MESSAGE_ID: "topic_2.2.2", + }, + }, + ] + self.memory_exporter.clear() + + next_record_mock.side_effect = [ + self.consumer_record_factory( + 1, + headers=( + ( + "traceparent", + b"00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01", + ), + ), + ), + self.consumer_record_factory(2, headers=()), + ] + + await consumer.getone() + next_record_mock.assert_awaited_with(()) + + first_span = self.memory_exporter.get_finished_spans()[0] + self.assertEqual( + format_trace_id(first_span.get_span_context().trace_id), + "03afa25236b8cd948fa853d67038ac79", + ) + + await consumer.getone() + next_record_mock.assert_awaited_with(()) + + span_list = self.memory_exporter.get_finished_spans() + self._compare_spans(span_list, expected_spans) + + async def test_getone_baggage(self) -> None: + received_baggage = None + + async def async_consume_hook(span, *_) -> None: + nonlocal received_baggage + received_baggage = baggage.get_all(set_span_in_context(span)) + + AIOKafkaInstrumentor().uninstrument() + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_consume_hook=async_consume_hook, + ) + + consumer = await self.consumer_factory() + next_record_mock: mock.AsyncMock = consumer._fetcher.next_record + + self.memory_exporter.clear() + + next_record_mock.side_effect = [ + self.consumer_record_factory( + 1, + headers=( + ( + "traceparent", + b"00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01", + ), + ("baggage", b"foo=bar"), + ), + ), + ] + + await consumer.getone() + next_record_mock.assert_awaited_with(()) + + self.assertEqual(received_baggage, {"foo": "bar"}) + + async def test_getone_consume_hook(self) -> None: + async_consume_hook_mock = mock.AsyncMock() + + AIOKafkaInstrumentor().uninstrument() + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_consume_hook=async_consume_hook_mock, + ) + + consumer = await self.consumer_factory() + next_record_mock: mock.AsyncMock = consumer._fetcher.next_record + + next_record_mock.side_effect = [ + self.consumer_record_factory(1, headers=()) + ] + + await consumer.getone() + + async_consume_hook_mock.assert_awaited_once() + + async def test_send(self) -> None: + AIOKafkaInstrumentor().uninstrument() + AIOKafkaInstrumentor().instrument(tracer_provider=self.tracer_provider) + + producer = await self.producer_factory() + add_message_mock: mock.AsyncMock = ( + producer._message_accumulator.add_message + ) + + tracer = self.tracer_provider.get_tracer(__name__) + with tracer.start_as_current_span("test_span") as span: + await producer.send("topic_1", b"value_1") + + add_message_mock.assert_awaited_with( + TopicPartition(topic="topic_1", partition=1), + None, + b"value_1", + 40.0, + timestamp_ms=None, + headers=[("traceparent", mock.ANY)], ) + add_message_mock.call_args_list[0].kwargs["headers"][0][1].startswith( + f"00-{format_trace_id(span.get_span_context().trace_id)}-".encode() + ) + + await producer.send("topic_2", b"value_2") + add_message_mock.assert_awaited_with( + TopicPartition(topic="topic_2", partition=1), + None, + b"value_2", + 40.0, + timestamp_ms=None, + headers=[("traceparent", mock.ANY)], + ) + + async def test_send_baggage(self) -> None: + AIOKafkaInstrumentor().uninstrument() + AIOKafkaInstrumentor().instrument(tracer_provider=self.tracer_provider) + + producer = await self.producer_factory() + add_message_mock: mock.AsyncMock = ( + producer._message_accumulator.add_message + ) + + tracer = self.tracer_provider.get_tracer(__name__) + ctx = baggage.set_baggage("foo", "bar") + context.attach(ctx) + + with tracer.start_as_current_span("test_span", context=ctx): + await producer.send("topic_1", b"value_1") + + add_message_mock.assert_awaited_with( + TopicPartition(topic="topic_1", partition=1), + None, + b"value_1", + 40.0, + timestamp_ms=None, + headers=[("traceparent", mock.ANY), ("baggage", b"foo=bar")], + ) + + async def test_send_produce_hook(self) -> None: + async_produce_hook_mock = mock.AsyncMock() + + AIOKafkaInstrumentor().uninstrument() + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_produce_hook=async_produce_hook_mock, + ) + + producer = await self.producer_factory() + + await producer.send("topic_1", b"value_1") + + async_produce_hook_mock.assert_awaited_once() + + def _compare_spans( + self, spans: Sequence[ReadableSpan], expected_spans: List[dict] + ) -> None: + self.assertEqual(len(spans), len(expected_spans)) + for span, expected_span in zip(spans, expected_spans): + self.assertEqual(expected_span["name"], span.name) + self.assertEqual(expected_span["kind"], span.kind) + self.assertEqual( + expected_span["attributes"], dict(span.attributes) + ) diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py index b1b2792608..09a8655309 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py @@ -23,7 +23,7 @@ _create_consumer_span, _extract_send_partition, _get_span_name, - _wrap_anext, + _wrap_getone, _wrap_send, ) from opentelemetry.trace import SpanKind @@ -187,7 +187,7 @@ async def test_wrap_next( original_next_callback = mock.AsyncMock() kafka_consumer = mock.MagicMock() - wrapped_next = _wrap_anext(tracer, consume_hook) + wrapped_next = _wrap_getone(tracer, consume_hook) record = await wrapped_next( original_next_callback, kafka_consumer, self.args, self.kwargs ) diff --git a/tox.ini b/tox.ini index e0a5a71131..2b0995d8fc 100644 --- a/tox.ini +++ b/tox.ini @@ -444,6 +444,7 @@ commands_pre = aiokafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api aiokafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions aiokafka: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + aiokafka: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils aiokafka: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt kafka-python: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api From eccb05c808a7d797ef5b6ecefed3590664426fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:50:07 -0300 Subject: [PATCH 190/335] tests: bump cryptography to 43.0.1 in test-requirements (#2889) Co-authored-by: Diego Hurtado --- .../opentelemetry-instrumentation-boto/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index bb56100ecb..41c228a1fe 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -5,7 +5,7 @@ botocore==1.34.44 certifi==2024.7.4 cffi==1.17.0 charset-normalizer==3.3.2 -cryptography==42.0.5 +cryptography==43.0.1 Deprecated==1.2.14 docker==7.0.0 idna==3.7 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index f0ceb9f467..e5e698c1cf 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -5,7 +5,7 @@ botocore==1.31.80 certifi==2024.7.4 cffi==1.17.0 charset-normalizer==3.3.2 -cryptography==42.0.5 +cryptography==43.0.1 Deprecated==1.2.14 docker==7.0.0 idna==3.7 From 65b703529b71d5650d8d6d0be2ed95518d16013f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 2 Oct 2024 06:58:32 -0300 Subject: [PATCH 191/335] Update CHANGELOG.md (#2888) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30440c2dce..d25b0b3a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,13 +14,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aiokafka` Add instrumentor and auto instrumentation support for aiokafka ([#2082](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2082)) - ### Fixed - `opentelemetry-instrumentation-aiokafka` Wrap `AIOKafkaConsumer.getone()` instead of `AIOKafkaConsumer.__anext__` ([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874)) -## Version 1.27.0/0.48b0 () +## Version 1.27.0/0.48b0 (2024-08-28) ### Added From 6bb6d3896d861c875ef3bbc0fec4c07347c9b00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Po=C5=BAniak?= Date: Thu, 3 Oct 2024 00:42:33 +0200 Subject: [PATCH 192/335] Add additional attributes for redis.search methods create_index, search (#2635) --- CHANGELOG.md | 2 + .../instrumentation/redis/__init__.py | 73 ++++++++++++++++++- .../instrumentation/redis/util.py | 12 +++ .../tests/docker-compose.yml | 2 +- .../tests/redis/test_redis_functional.py | 69 ++++++++++++++++++ 5 files changed, 153 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d25b0b3a98..e4dcc10c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2860](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2860)) - `opentelemetry-instrumentation-aiokafka` Add instrumentor and auto instrumentation support for aiokafka ([#2082](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2082)) +- `opentelemetry-instrumentation-redis` Add additional attributes for methods create_index and search, rename those spans + ([#2635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2635)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index 08337c2d4a..1d3b8b8a87 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -102,6 +102,8 @@ def response_hook(span, instance, response): from opentelemetry.instrumentation.redis.util import ( _extract_conn_attributes, _format_command_args, + _set_span_attribute_if_value, + _value_or_none, ) from opentelemetry.instrumentation.redis.version import __version__ from opentelemetry.instrumentation.utils import unwrap @@ -126,6 +128,8 @@ def response_hook(span, instance, response): _REDIS_CLUSTER_VERSION = (4, 1, 0) _REDIS_ASYNCIO_CLUSTER_VERSION = (4, 3, 2) +_FIELD_TYPES = ["NUMERIC", "TEXT", "GEO", "TAG", "VECTOR"] + def _set_connection_attributes(span, conn): if not span.is_recording() or not hasattr(conn, "connection_pool"): @@ -138,7 +142,12 @@ def _set_connection_attributes(span, conn): def _build_span_name(instance, cmd_args): if len(cmd_args) > 0 and cmd_args[0]: - name = cmd_args[0] + if cmd_args[0] == "FT.SEARCH": + name = "redis.search" + elif cmd_args[0] == "FT.CREATE": + name = "redis.create_index" + else: + name = cmd_args[0] else: name = instance.connection_pool.connection_kwargs.get("db", 0) return name @@ -181,7 +190,6 @@ def _instrument( def _traced_execute_command(func, instance, args, kwargs): query = _format_command_args(args) name = _build_span_name(instance, args) - with tracer.start_as_current_span( name, kind=trace.SpanKind.CLIENT ) as span: @@ -189,9 +197,14 @@ def _traced_execute_command(func, instance, args, kwargs): span.set_attribute(SpanAttributes.DB_STATEMENT, query) _set_connection_attributes(span, instance) span.set_attribute("db.redis.args_length", len(args)) + if span.name == "redis.create_index": + _add_create_attributes(span, args) if callable(request_hook): request_hook(span, instance, args, kwargs) response = func(*args, **kwargs) + if span.is_recording(): + if span.name == "redis.search": + _add_search_attributes(span, response, args) if callable(response_hook): response_hook(span, instance, response) return response @@ -202,9 +215,7 @@ def _traced_execute_pipeline(func, instance, args, kwargs): resource, span_name, ) = _build_span_meta_data_for_pipeline(instance) - exception = None - with tracer.start_as_current_span( span_name, kind=trace.SpanKind.CLIENT ) as span: @@ -230,6 +241,60 @@ def _traced_execute_pipeline(func, instance, args, kwargs): return response + def _add_create_attributes(span, args): + _set_span_attribute_if_value( + span, "redis.create_index.index", _value_or_none(args, 1) + ) + # According to: https://github.com/redis/redis-py/blob/master/redis/commands/search/commands.py#L155 schema is last argument for execute command + try: + schema_index = args.index("SCHEMA") + except ValueError: + return + schema = args[schema_index:] + field_attribute = "" + # Schema in format: + # [first_field_name, first_field_type, first_field_some_attribute1, first_field_some_attribute2, second_field_name, ...] + field_attribute = "".join( + f"Field(name: {schema[index - 1]}, type: {schema[index]});" + for index in range(1, len(schema)) + if schema[index] in _FIELD_TYPES + ) + _set_span_attribute_if_value( + span, + "redis.create_index.fields", + field_attribute, + ) + + def _add_search_attributes(span, response, args): + _set_span_attribute_if_value( + span, "redis.search.index", _value_or_none(args, 1) + ) + _set_span_attribute_if_value( + span, "redis.search.query", _value_or_none(args, 2) + ) + # Parse response from search + # https://redis.io/docs/latest/commands/ft.search/ + # Response in format: + # [number_of_returned_documents, index_of_first_returned_doc, first_doc(as a list), index_of_second_returned_doc, second_doc(as a list) ...] + # Returned documents in array format: + # [first_field_name, first_field_value, second_field_name, second_field_value ...] + number_of_returned_documents = _value_or_none(response, 0) + _set_span_attribute_if_value( + span, "redis.search.total", number_of_returned_documents + ) + if "NOCONTENT" in args or not number_of_returned_documents: + return + for document_number in range(number_of_returned_documents): + document_index = _value_or_none(response, 1 + 2 * document_number) + if document_index: + document = response[2 + 2 * document_number] + for attribute_name_index in range(0, len(document), 2): + _set_span_attribute_if_value( + span, + f"redis.search.xdoc_{document_index}.{document[attribute_name_index]}", + document[attribute_name_index + 1], + ) + pipeline_class = ( "BasePipeline" if redis.VERSION < (3, 0, 0) else "Pipeline" ) diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py index 4703bc271f..24ca387861 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py @@ -68,3 +68,15 @@ def _format_command_args(args): out_str = "" return out_str + + +def _set_span_attribute_if_value(span, name, value): + if value is not None and value != "": + span.set_attribute(name, value) + + +def _value_or_none(values, n): + try: + return values[n] + except IndexError: + return None diff --git a/tests/opentelemetry-docker-tests/tests/docker-compose.yml b/tests/opentelemetry-docker-tests/tests/docker-compose.yml index 59f0e42d3d..02a3721d9b 100644 --- a/tests/opentelemetry-docker-tests/tests/docker-compose.yml +++ b/tests/opentelemetry-docker-tests/tests/docker-compose.yml @@ -24,7 +24,7 @@ services: POSTGRES_PASSWORD: testpassword POSTGRES_DB: opentelemetry-tests otredis: - image: redis:4.0-alpine + image: redis/redis-stack:7.2.0-v12 ports: - "127.0.0.1:6379:6379" otrediscluster: diff --git a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py index 481b8d21c8..d02febca10 100644 --- a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py +++ b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py @@ -18,6 +18,15 @@ import redis import redis.asyncio +from redis.exceptions import ResponseError +from redis.commands.search.indexDefinition import IndexDefinition, IndexType +from redis.commands.search.aggregation import AggregateRequest +from redis.commands.search.query import Query +from redis.commands.search.field import ( + TextField, + VectorField, +) + from opentelemetry import trace from opentelemetry.instrumentation.redis import RedisInstrumentor from opentelemetry.semconv.trace import SpanAttributes @@ -614,3 +623,63 @@ def test_get(self): self.assertEqual( span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" ) + + +class TestRedisearchInstrument(TestBase): + def setUp(self): + super().setUp() + self.redis_client = redis.Redis(port=6379) + self.redis_client.flushall() + self.embedding_dim = 256 + RedisInstrumentor().instrument(tracer_provider=self.tracer_provider) + self.prepare_data() + self.create_index() + + def tearDown(self): + RedisInstrumentor().uninstrument() + super().tearDown() + + def prepare_data(self): + try: + self.redis_client.ft("idx:test_vss").dropindex(True) + except ResponseError: + print("No such index") + item = {"name": "test", + "value": "test_value", + "embeddings": [0.1] * 256} + pipeline = self.redis_client.pipeline() + pipeline.json().set(f"test:001", "$", item) + res = pipeline.execute() + assert False not in res + + def create_index(self): + schema = ( + TextField("$.name", no_stem=True, as_name="name"), + TextField("$.value", no_stem=True, as_name="value"), + VectorField("$.embeddings", + "FLAT", + { + "TYPE": "FLOAT32", + "DIM": self.embedding_dim, + "DISTANCE_METRIC": "COSINE", + }, + as_name="vector",), + ) + definition = IndexDefinition(prefix=["test:"], index_type=IndexType.JSON) + res = self.redis_client.ft("idx:test_vss").create_index(fields=schema, definition=definition) + assert "OK" in str(res) + + def test_redis_create_index(self): + spans = self.memory_exporter.get_finished_spans() + span = next(span for span in spans if span.name == "redis.create_index") + assert "redis.create_index.fields" in span.attributes + + def test_redis_query(self): + query = "@name:test" + res = self.redis_client.ft("idx:test_vss").search(Query(query)) + + spans = self.memory_exporter.get_finished_spans() + span = next(span for span in spans if span.name == "redis.search") + + assert span.attributes.get("redis.search.query") == query + assert span.attributes.get("redis.search.total") == 1 From 6a54106f5b39ac4d09482498603c1246f4097c2d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 9 Oct 2024 09:20:02 -0700 Subject: [PATCH 193/335] Automate per-package release for specific components (#2875) --- .../package-prepare-patch-release.yml | 116 ++++++++++ .github/workflows/package-prepare-release.yml | 194 +++++++++++++++++ .github/workflows/package-release.yml | 156 ++++++++++++++ .../workflows/publish-a-package-from-tag.yml | 31 --- .github/workflows/release.yml | 65 +----- CHANGELOG.md | 4 + RELEASING.md | 41 ++++ eachdist.ini | 1 + instrumentation/README.md | 1 + .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../LICENSE | 201 ++++++++++++++++++ .../README.rst | 25 +++ .../pyproject.toml | 49 +++++ .../instrumentation/test/__init__.py | 17 ++ .../instrumentation/test/package.py | 20 ++ .../instrumentation/test/version.py | 15 ++ .../test-requirements.txt | 14 ++ .../tests/__init__.py | 23 ++ .../pyproject.toml | 1 + .../instrumentation/bootstrap_gen.py | 1 + .../CHANGELOG.md | 13 ++ .../opentelemetry/propagators/aws/version.py | 2 +- .../resource/detector/azure/version.py | 2 +- scripts/build_a_package.sh | 29 ++- scripts/eachdist.py | 49 ++++- scripts/generate_release_notes.sh | 26 +++ scripts/merge_changelog_to_main.sh | 50 +++++ .../CHANGELOG.md | 13 ++ .../sdk/extension/aws/version.py | 2 +- 30 files changed, 1058 insertions(+), 107 deletions(-) create mode 100644 .github/workflows/package-prepare-patch-release.yml create mode 100644 .github/workflows/package-prepare-release.yml create mode 100644 .github/workflows/package-release.yml delete mode 100644 .github/workflows/publish-a-package-from-tag.yml create mode 100644 instrumentation/opentelemetry-instrumentation-test/LICENSE create mode 100644 instrumentation/opentelemetry-instrumentation-test/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-test/pyproject.toml create mode 100644 instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py create mode 100644 instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py create mode 100644 instrumentation/opentelemetry-instrumentation-test/test-requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-test/tests/__init__.py create mode 100644 propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md create mode 100755 scripts/generate_release_notes.sh create mode 100755 scripts/merge_changelog_to_main.sh create mode 100644 sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md diff --git a/.github/workflows/package-prepare-patch-release.yml b/.github/workflows/package-prepare-patch-release.yml new file mode 100644 index 0000000000..e9cc7d55ba --- /dev/null +++ b/.github/workflows/package-prepare-patch-release.yml @@ -0,0 +1,116 @@ +name: "[Package] Prepare patch release" +on: + workflow_dispatch: + inputs: + package: + type: choice + options: + - opentelemetry-propagator-aws-xray + - opentelemetry-resource-detector-azure + - opentelemetry-sdk-extension-aws + description: 'Package to be released' + required: true +jobs: + prepare-patch-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Verify prerequisites + run: | + if [[ $GITHUB_REF_NAME != package-release/${{ inputs.package }}/v* ]]; then + echo this workflow should only be run against package-release/${{ inputs.package }}* branches, but is running on $GITHUB_REF_NAME + exit 1 + fi + + path=./$(./scripts/eachdist.py find-package --package ${{ inputs.package }}) + changelog=$path/CHANGELOG.md + + if [ ! -f $changelog ]; then + echo "missing $changelog file" + exit 1 + fi + + if ! grep --quiet "^## Unreleased$" CHANGELOG.md; then + echo the $changelog is missing an \"Unreleased\" section + exit 1 + fi + + version=$(./scripts/eachdist.py version --package ${{ inputs.package }}) + + version_file=$(find $path -type f -path "*version*.py") + file_count=$(echo "$version_file" | wc -l) + + if [ "$file_count" -ne 1 ]; then + echo "Error: expected one version file, found $file_count" + echo "$version_file" + exit 1 + fi + + if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then + # 1.2.3 or 1.2.3rc1 + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + patch="${BASH_REMATCH[3]}" + next_version="$major.$minor.$((patch + 1))" + release_branch_name="package-release/${{ inputs.package }}/v$major.$minor.x" + elif [[ $version =~ ^([0-9]+)\.([0-9]+)b([0-9]+)$ ]]; then + # 0.1b1 + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + patch="${BASH_REMATCH[3]}" + next_version="$major.${minor}b$((patch + 1))" + release_branch_name="package-release/${{ inputs.package }}/v$major.${minor}bx" + else + echo "unexpected version: '$version'" + exit 1 + fi + + if [[ $GITHUB_REF_NAME != $release_branch_name ]]; then + echo this workflow should only be run against $release_branch_name branch, but is running on $GITHUB_REF_NAME + exit 1 + fi + + echo "PACKAGE_NAME=${{ inputs.package }}" >> $GITHUB_ENV + echo "VERSION=$version" >> $GITHUB_ENV + echo "NEXT_VERSION=$next_version" >> $GITHUB_ENV + echo "CHANGELOG=$changelog" >> $GITHUB_ENV + echo "VERSION_FILE=$version_file" >> $GITHUB_ENV + + - name: Update version + run: | + # replace the version in the version file (1.2.3 -> 1.2.4) + sed -i -E "s/__version__\s*=\s*\"${VERSION}\"/__version__ = \"${NEXT_VERSION}\"/g" $VERSION_FILE + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: 3.9 + - name: Install tox + run: pip install tox + - name: run tox + run: tox -e generate + + - name: Update the change log with the approximate release date + run: | + # the actual release date on main will be updated at the end of the release workflow + date=$(date "+%Y-%m-%d") + sed -Ei "s/^## Unreleased$/## Unreleased\n\n## Version ${NEXT_VERSION} ($date)/" ${CHANGELOG} + + - name: Use CLA approved github bot + run: .github/scripts/use-cla-approved-github-bot.sh + + - name: Create pull request + env: + # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows + GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} + run: | + message="Prepare patch release for ${PACKAGE_NAME} v${NEXT_VERSION}" + branch="opentelemetrybot/patch-${PACKAGE_NAME}-version-to-v${NEXT_VERSION}" + + git commit -a -m "$message" + git push origin HEAD:$branch + gh pr create --title "[$GITHUB_REF_NAME] $message" \ + --body "$message." \ + --head $branch \ + --base $GITHUB_REF_NAME diff --git a/.github/workflows/package-prepare-release.yml b/.github/workflows/package-prepare-release.yml new file mode 100644 index 0000000000..61dd1eb971 --- /dev/null +++ b/.github/workflows/package-prepare-release.yml @@ -0,0 +1,194 @@ +name: "[Package] Prepare release" +on: + workflow_dispatch: + inputs: + package: + type: choice + options: + - opentelemetry-propagator-aws-xray + - opentelemetry-resource-detector-azure + - opentelemetry-sdk-extension-aws + description: 'Package to be released' + required: true + +jobs: + prereqs: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.verify.outputs.version }} + changelog: ${{ steps.verify.outputs.changelog }} + version_file: ${{ steps.verify.outputs.version_file }} + release_branch_name: ${{ steps.verify.outputs.release_branch_name }} + next_version: ${{ steps.verify.outputs.next_version }} + steps: + - uses: actions/checkout@v4 + + - id: verify + name: Verify prerequisites + run: | + if [[ $GITHUB_REF_NAME != main ]]; then + echo this workflow should only be run against main + exit 1 + fi + + path=./$(./scripts/eachdist.py find-package --package ${{ inputs.package }}) + changelog=$path/CHANGELOG.md + + if [ ! -f $changelog ]; then + echo "missing $changelog file" + exit 1 + fi + + if ! grep --quiet "^## Unreleased$" $changelog; then + echo the $changelog is missing an \"Unreleased\" section + exit 1 + fi + + version_dev=$(./scripts/eachdist.py version --package ${{ inputs.package }}) + + if [[ ! $version_dev =~ ^([0-9]+)\.([0-9]+)[\.|b]{1}([0-9]+).*.dev$ ]]; then + echo "unexpected version: $version" + exit 1 + fi + + version=${version_dev%.dev} + + version_file=$(find $path -type f -path "*version*.py") + file_count=$(echo "$version_file" | wc -l) + + if [ "$file_count" -ne 1 ]; then + echo "Error: expected one version file, found $file_count" + echo "$version_file" + exit 1 + fi + + if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then + # 1.2.3 or 1.2.3rc1 + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + release_branch_name="package-release/${{ inputs.package }}/v$major.$minor.x" + next_version="$major.$((minor + 1)).0" + elif [[ $version =~ ^([0-9]+)\.([0-9]+)b([0-9]+)$ ]]; then + # 0.1b1 + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + release_branch_name="package-release/${{ inputs.package }}/v$major.${minor}bx" + next_version="$major.$((minor + 1))b0" + else + echo "unexpected version: '$version'" + exit 1 + fi + + echo "version=$version" >> $GITHUB_OUTPUT + echo "changelog=$changelog" >> $GITHUB_OUTPUT + echo "version_file=$version_file" >> $GITHUB_OUTPUT + echo "release_branch_name=$release_branch_name" >> $GITHUB_OUTPUT + echo "next_version=$next_version" >> $GITHUB_OUTPUT + + create-pull-request-against-release-branch: + runs-on: ubuntu-latest + needs: prereqs + steps: + - uses: actions/checkout@v4 + + - name: Set environment variables + run: | + echo "RELEASE_BRANCH_NAME=${{ needs.prereqs.outputs.release_branch_name }}" >> $GITHUB_ENV + echo "VERSION=${{ needs.prereqs.outputs.version }}" >> $GITHUB_ENV + echo "CHANGELOG=${{ needs.prereqs.outputs.changelog }}" >> $GITHUB_ENV + echo "VERSION_FILE=${{ needs.prereqs.outputs.version_file }}" >> $GITHUB_ENV + echo "PACKAGE_NAME=${{ github.event.inputs.package }}" >> $GITHUB_ENV + + - name: Create package release branch + run: | + git push origin HEAD:$RELEASE_BRANCH_NAME + + - name: Update package version + run: | + # replace the version in the version file (1.2.3dev -> 1.2.3) + sed -i -E "s/__version__\s*=\s*\"${VERSION}\.dev\"/__version__ = \"${VERSION}\"/g" $VERSION_FILE + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: 3.9 + - name: Install tox + run: pip install tox + - name: run tox + run: tox -e generate + + - name: Update the change log with the approximate release date + run: | + date=$(date "+%Y-%m-%d") + sed -Ei "s/^## Unreleased$/## Version ${VERSION} ($date)/" ${CHANGELOG} + + - name: Use CLA approved github bot + run: .github/scripts/use-cla-approved-github-bot.sh + + - name: Create pull request against the release branch + env: + # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows + GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} + run: | + message="Prepare release for ${PACKAGE_NAME} v${VERSION}" + branch="opentelemetrybot/prepare-${RELEASE_BRANCH_NAME}" + + git commit -a -m "$message" + git push origin HEAD:$branch + gh pr create --title "[$RELEASE_BRANCH_NAME] $message" \ + --body "$message." \ + --head $branch \ + --base $RELEASE_BRANCH_NAME + + create-pull-request-against-main: + runs-on: ubuntu-latest + needs: prereqs + steps: + - uses: actions/checkout@v4 + + - name: Set environment variables + run: | + echo "PACKAGE_NAME=${{ github.event.inputs.package }}" >> $GITHUB_ENV + echo "VERSION=${{ needs.prereqs.outputs.version }}" >> $GITHUB_ENV + echo "VERSION_FILE=${{ needs.prereqs.outputs.version_file }}" >> $GITHUB_ENV + echo "NEXT_VERSION=${{ needs.prereqs.outputs.next_version }}" >> $GITHUB_ENV + echo "CHANGELOG=${{ needs.prereqs.outputs.changelog }}" >> $GITHUB_ENV + + - name: Update version + run: | + # replace the version in the version file (1.2.3dev -> 1.3.3.dev) + sed -i -E "s/__version__\s*=\s*\"${VERSION}\.dev\"/__version__ = \"${NEXT_VERSION}.dev\"/g" $VERSION_FILE + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: 3.9 + - name: Install tox + run: pip install tox + - name: run tox + run: tox -e generate + + - name: Update the change log on main + run: | + # the actual release date on main will be updated at the end of the release workflow + date=$(date "+%Y-%m-%d") + sed -Ei "s/^## Unreleased$/## Unreleased\n\n## Version ${VERSION} ($date)/" ${CHANGELOG} + + - name: Use CLA approved github bot + run: .github/scripts/use-cla-approved-github-bot.sh + + - name: Create pull request against main + env: + # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows + GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} + run: | + message="Update ${PACKAGE_NAME} version to v${NEXT_VERSION}" + body="Update \`${PACKAGE_NAME}\` version to v\`${NEXT_VERSION}\`." + branch="opentelemetrybot/update-${PACKAGE_NAME}-version-to-v${NEXT_VERSION}" + + git commit -a -m "$message" + git push origin HEAD:$branch + gh pr create --title "$message" \ + --body "$body" \ + --head $branch \ + --base main diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml new file mode 100644 index 0000000000..823f2c83d2 --- /dev/null +++ b/.github/workflows/package-release.yml @@ -0,0 +1,156 @@ +name: "[Package] Release" +on: + workflow_dispatch: + inputs: + package: + type: choice + options: + - opentelemetry-propagator-aws-xray + - opentelemetry-resource-detector-azure + - opentelemetry-sdk-extension-aws + description: 'Package to be released' + required: true +jobs: + release: + runs-on: ubuntu-latest + steps: + - run: | + if [[ $GITHUB_REF_NAME != package-release/${{ inputs.package }}* ]]; then + echo this workflow should only be run against package-release/${{ inputs.package }}* branches + exit 1 + fi + + - uses: actions/checkout@v4 + + - name: Set environment variables + run: | + version=$(./scripts/eachdist.py version --package ${{ inputs.package }}) + if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + patch="${BASH_REMATCH[3]}" + if [[ $patch != 0 ]]; then + prior_version_when_patch="${major}.${minor}.$((patch - 1))" + fi + elif [[ $version =~ ^([0-9]+)\.([0-9]+)b([0-9]+)$ ]]; then + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + patch="${BASH_REMATCH[3]}" + + if [[ $patch != 0 ]]; then + prior_version_when_patch="${major}.${minor}b$((patch - 1))" + fi + else + echo "unexpected version: $version" + exit 1 + fi + + path=$(./scripts/eachdist.py find-package --package ${{ inputs.package }}) + echo "CHANGELOG=./$path/CHANGELOG.md" >> $GITHUB_ENV + echo "PACKAGE_NAME=${{ inputs.package }}" >> $GITHUB_ENV + echo "VERSION=$version" >> $GITHUB_ENV + echo "RELEASE_TAG=${{ inputs.package }}==$version" >> $GITHUB_ENV + echo "PRIOR_VERSION_WHEN_PATCH=$prior_version_when_patch" >> $GITHUB_ENV + + # check out main branch to verify there won't be problems with merging the change log + # at the end of this workflow + - uses: actions/checkout@v4 + with: + ref: main + + - name: Check that change log update was merged to main + run: | + if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then + # not making a patch release + if ! grep --quiet "^## Version ${VERSION}" ${CHANGELOG}; then + echo the pull request generated by prepare-release-branch.yml needs to be merged first + exit 1 + fi + fi + + # back to the release branch + - uses: actions/checkout@v4 + + # next few steps publish to pypi + - uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Build wheels + run: ./scripts/build_a_package.sh + + - name: Install twine + run: | + pip install twine + + # The step below publishes to testpypi in order to catch any issues + # with the package configuration that would cause a failure to upload + # to pypi. One example of such a failure is if a classifier is + # rejected by pypi (e.g "3 - Beta"). This would cause a failure during the + # middle of the package upload causing the action to fail, and certain packages + # might have already been updated, this would be bad. + # EDIT: 5/31/2024 - TestPypi now requires a verified email. Commenting out as a temporary measure + # until we found TestPypi credentials. + # - name: Publish to TestPyPI + # env: + # TWINE_USERNAME: '__token__' + # TWINE_PASSWORD: ${{ secrets.test_pypi_token }} + # run: | + # twine upload --repository testpypi --skip-existing --verbose dist/* + + - name: Publish to PyPI + env: + TWINE_USERNAME: '__token__' + TWINE_PASSWORD: ${{ secrets.test_pypi_token }} + run: | + twine upload --repository testpypi --skip-existing --verbose dist/* + + - name: Generate release notes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: ./scripts/generate_release_notes.sh + + - name: Create GitHub release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create --target $GITHUB_REF_NAME \ + --title "${PACKAGE_NAME} ${VERSION}" \ + --notes-file /tmp/release-notes.txt \ + --discussion-category announcements \ + $RELEASE_TAG + + - uses: actions/checkout@v4 + with: + ref: main + + - name: Copy change log updates to main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: ./scripts/merge_changelog_to_main.sh + + - name: Use CLA approved github bot + run: .github/scripts/use-cla-approved-github-bot.sh + + - name: Create pull request against main + env: + # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows + GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} + run: | + message="Copy changelog updates from $GITHUB_REF_NAME" + body="Copy changelog updates from \`$GITHUB_REF_NAME\`." + branch="opentelemetrybot/changelog-${GITHUB_REF_NAME//\//-}" + + if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then + if git diff --quiet; then + echo there are no updates needed to the change log on main, not creating pull request + exit 0 # success + fi + fi + + git commit -a -m "$message" + git push origin HEAD:$branch + gh pr create --title "$message" \ + --body "$body" \ + --head $branch \ + --base main diff --git a/.github/workflows/publish-a-package-from-tag.yml b/.github/workflows/publish-a-package-from-tag.yml deleted file mode 100644 index a64f5fcf15..0000000000 --- a/.github/workflows/publish-a-package-from-tag.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Publish a Package from Tag - -on: - push: - tags: - - 'opentelemetry-*==[1-9]*.*' - -jobs: - publish-a-package: - name: Publish package from tag - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.9' - - name: Log tag that triggered publish workflow - run: echo "Attempting to publish package from tag $GITHUB_REF" - - name: Build wheel for tag - run: ./scripts/build_a_package.sh - - name: Install twine - run: | - pip install twine - # We don't need to publish to TestPyPI because we only publish 1 package. - # If it fails no other work needs to be reversed. - - name: Publish to PyPI - env: - TWINE_USERNAME: '__token__' - TWINE_PASSWORD: ${{ secrets.pypi_password }} - run: | - twine upload --skip-existing --verbose dist/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ec544b43c8..964d6f93df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: echo "STABLE_VERSION=$stable_version" >> $GITHUB_ENV echo "UNSTABLE_VERSION=$unstable_version" >> $GITHUB_ENV - + echo "CHANGELOG=CHANGELOG.md" >> $GITHUB_ENV echo "PRIOR_VERSION_WHEN_PATCH=$prior_version_when_patch" >> $GITHUB_ENV - run: | @@ -101,23 +101,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - # conditional block not indented because of the heredoc - if [[ ! -z $PRIOR_VERSION_WHEN_PATCH ]]; then - cat > /tmp/release-notes.txt << EOF - This is a patch release on the previous $PRIOR_VERSION_WHEN_PATCH release, fixing the issue(s) below. - - EOF - fi - - # CHANGELOG_SECTION.md is also used at the end of the release workflow - # for copying the change log updates to main - sed -n "0,/^## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} /d;/^## Version /q;p" CHANGELOG.md \ - > /tmp/CHANGELOG_SECTION.md - - # the complex perl regex is needed because markdown docs render newlines as soft wraps - # while release notes render them as line breaks - perl -0pe 's/(?> /tmp/release-notes.txt + echo "VERSION=${STABLE_VERSION}\/${UNSTABLE_VERSION}" >> $GITHUB_ENV + ./scripts/generate_release_notes.sh - name: Create GitHub release env: @@ -138,47 +123,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then - # this was not a patch release, so the version exists already in the CHANGELOG.md - - # update the release date - date=$(gh release view v$STABLE_VERSION --json publishedAt --jq .publishedAt | sed 's/T.*//') - sed -Ei "s/## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} .*/## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/" CHANGELOG.md - - # the entries are copied over from the release branch to support workflows - # where change log entries may be updated after preparing the release branch - - # copy the portion above the release, up to and including the heading - sed -n "0,/^## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/p" CHANGELOG.md > /tmp/CHANGELOG.md - - # copy the release notes - cat /tmp/CHANGELOG_SECTION.md >> /tmp/CHANGELOG.md - - # copy the portion below the release - sed -n "0,/^## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} /d;0,/^## Version /{/^## Version/!d};p" CHANGELOG.md \ - >> /tmp/CHANGELOG.md - - # update the real CHANGELOG.md - cp /tmp/CHANGELOG.md CHANGELOG.md - else - # this was a patch release, so the version does not exist already in the CHANGELOG.md - - # copy the portion above the top-most release, not including the heading - sed -n "0,/^## Version /{ /^## Version /!p }" CHANGELOG.md > /tmp/CHANGELOG.md - - # add the heading - date=$(gh release view v$STABLE_VERSION --json publishedAt --jq .publishedAt | sed 's/T.*//') - echo "## Version ${STABLE_VERSION}/${UNSTABLE_VERSION} ($date)" >> /tmp/CHANGELOG.md - - # copy the release notes - cat /tmp/CHANGELOG_SECTION.md >> /tmp/CHANGELOG.md - - # copy the portion starting from the top-most release - sed -n "/^## Version /,\$p" CHANGELOG.md >> /tmp/CHANGELOG.md - - # update the real CHANGELOG.md - cp /tmp/CHANGELOG.md CHANGELOG.md - fi + echo "VERSION=${STABLE_VERSION}\/${UNSTABLE_VERSION}" >> $GITHUB_ENV + echo "RELEASE_TAG=$STABLE_VERSION" >> $GITHUB_ENV + ./scripts/merge_changelog_to_main.sh - name: Use CLA approved github bot run: .github/scripts/use-cla-approved-github-bot.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index e4dcc10c7b..94b6c22af8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +> [!NOTE] +> The following components are released independently and maintain individual CHANGELOG files. +> Use [this search for a list of all CHANGELOG.md files in this repo](https://github.com/search?q=repo%3Aopen-telemetry%2Fopentelemetry-python-contrib+path%3A**%2FCHANGELOG.md&type=code). + ## Unreleased ### Added diff --git a/RELEASING.md b/RELEASING.md index 5a359159fb..c1c923b705 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -12,6 +12,21 @@ * Merge the one targeted towards the release branch. * The builds will fail for the `main` pr because of validation rules. Follow the [release workflow](https://github.com/open-telemetry/opentelemetry-python/blob/main/RELEASING.md) for the core repo up until this same point. Change the SHAs of each PR to point at each other to get the `main` builds to pass. +### Preparing a major or minor release for individual package + +> [!NOTE] +> Per-package release is supported for the following packages only: +> - opentelemetry-propagator-aws-xray +> - opentelemetry-resource-detector-azure +> - opentelemetry-sdk-extension-aws +> +> These libraries are also excluded from the general release. + +Package release preparation is handled by the [`[Package] Prepare release`](./.github/workflows/package-prepare-release.yml) workflow that allows +to pick a specific package to release. It follows the same versioning strategy and process as the general release. + +Long-term package release branch follows `package-release/{package-name}/v{major}.{minor}.x` (or `package-release/{package-name}/v{major}.{minor}bx`) naming pattern. + ## Preparing a new patch release * Backport pull request(s) to the release branch. @@ -27,6 +42,17 @@ e.g. `release/v1.9.x`, and click the "Run workflow" button below that. * Review and merge the pull request that it creates for updating the version. +### Preparing a patch release for individual package + +> [!NOTE] +> Per-package release is supported only for packages included in the corresponding workflow. Libraries that support per-package release are currently +> excluded from the general patch release. + +Per-package patch release preparation is handled by the [`[Package] Prepare patch release`](./.github/workflows/package-prepare-patch-release.yml) workflow that allows +to pick a specific package to release. + +The workflow can only be run against long-term release branch such as `package-release/{package-name}/v{major}.{minor}.x` or `package-release/{package-name}/v{major}.{minor}bx`. + ## Making the release * Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml). @@ -37,6 +63,21 @@ (note that if this is not a patch release then the change log on main may already be up-to-date, in which case no pull request will be created). +### Releasing individual package + +> [!NOTE] +> Per-package patch release is supported for the following packages only: +> - opentelemetry-propagator-aws-xray +> - opentelemetry-resource-detector-azure +> - opentelemetry-sdk-extension-aws +> +> These libraries are also excluded from the general patch release. + +Per-package release is handled by the [`[Package] Release`](./.github/workflows/package-release.yml) workflow that allows +to pick a specific package to release. + +The workflow can only be run against long-term release branch such as `package-release/{package-name}/v{major}.{minor}.x` or `package-release/{package-name}/v{major}.{minor}bx`. + ## Notes about version numbering for stable components * The version number for stable components in the `main` branch is always `X.Y.0.dev`, diff --git a/eachdist.ini b/eachdist.ini index 79c865b334..950b751685 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -50,6 +50,7 @@ packages= opentelemetry-resource-detector-azure opentelemetry-sdk-extension-aws opentelemetry-propagator-aws-xray + opentelemetry-instrumentation-test [lintroots] extraroots=examples/*,scripts/ diff --git a/instrumentation/README.md b/instrumentation/README.md index b87bf6f844..6bb47f6f9c 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -43,6 +43,7 @@ | [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | experimental | [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette ~= 0.13.0 | Yes | experimental | [opentelemetry-instrumentation-system-metrics](./opentelemetry-instrumentation-system-metrics) | psutil >= 5 | No | experimental +| [opentelemetry-instrumentation-test](./opentelemetry-instrumentation-test) | test | No | migration | [opentelemetry-instrumentation-threading](./opentelemetry-instrumentation-threading) | threading | No | experimental | [opentelemetry-instrumentation-tornado](./opentelemetry-instrumentation-tornado) | tornado >= 5.1.1 | Yes | experimental | [opentelemetry-instrumentation-tortoiseorm](./opentelemetry-instrumentation-tortoiseorm) | tortoise-orm >= 0.17.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index debc3ce033..6c1aad7d23 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-propagator-aws-xray ~= 1.0.1", "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-propagator-aws-xray ~= 1.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 797145b728..dae5b29661 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-propagator-aws-xray ~= 1.0.1", + "opentelemetry-propagator-aws-xray ~= 1.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-test/LICENSE b/instrumentation/opentelemetry-instrumentation-test/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-test/README.rst b/instrumentation/opentelemetry-instrumentation-test/README.rst new file mode 100644 index 0000000000..fe5aeea554 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/README.rst @@ -0,0 +1,25 @@ +OpenTelemetry TEst Middleware +============================= + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-test.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-test/ + + +This library provides a test middleware that can be used on any test framework. + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-test + +References +---------- + +* `OpenTelemetry TEst Middleware `_ +* `OpenTelemetry Project `_ +* `WSGI `_ +* `OpenTelemetry Python Examples `_ diff --git a/instrumentation/opentelemetry-instrumentation-test/pyproject.toml b/instrumentation/opentelemetry-instrumentation-test/pyproject.toml new file mode 100644 index 0000000000..78e12624d0 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-test" +dynamic = ["version"] +description = "test Middleware for OpenTelemetry" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.8" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "opentelemetry-api ~= 1.12", + "opentelemetry-instrumentation ~= 0.47b0", + "opentelemetry-semantic-conventions == 0.47b0", +] + +[project.optional-dependencies] +instruments = [] + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-test" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/test/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py new file mode 100644 index 0000000000..3401275a73 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py @@ -0,0 +1,17 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +This library provides a WSGI middleware that can be used on any WSGI framework +(such as Django / Flask / Web.py) to track requests timing through OpenTelemetry. +""" diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py new file mode 100644 index 0000000000..361eac89c9 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +_instruments = tuple() + +_supports_metrics = False + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py new file mode 100644 index 0000000000..0d3adda0a2 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "1.0.0b.dev" diff --git a/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt new file mode 100644 index 0000000000..743026e94a --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt @@ -0,0 +1,14 @@ +asgiref==3.8.1 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +tomli==2.0.1 +typing_extensions==4.9.0 +wrapt==1.16.0 +zipp==3.19.2 +opentelemetry-instrumentation==0.48b0 +-e instrumentation/opentelemetry-instrumentation-test diff --git a/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py new file mode 100644 index 0000000000..a0b2062b52 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py @@ -0,0 +1,23 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import pkg_resources + +# IMPORTANT: Only the TEst module needs this because it is always the first +# package that uses the `{rootdir}/*/tests/` path and gets installed by +# `eachdist.py` and according to `eachdist.ini`. + +# Naming the tests module as a namespace package ensures that +# relative imports will resolve properly for subsequent test packages, +# as it enables searching for a composite of multiple test modules. +pkg_resources.declare_namespace(__name__) diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 300895c1e0..b34226b669 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -71,6 +71,7 @@ dependencies = [ "opentelemetry-instrumentation-sqlite3==0.49b0.dev", "opentelemetry-instrumentation-starlette==0.49b0.dev", "opentelemetry-instrumentation-system-metrics==0.49b0.dev", + "opentelemetry-instrumentation-test==1.0.0b.dev", "opentelemetry-instrumentation-threading==0.49b0.dev", "opentelemetry-instrumentation-tornado==0.49b0.dev", "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index cc9af1de80..ff6065d058 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -194,6 +194,7 @@ "opentelemetry-instrumentation-dbapi==0.49b0.dev", "opentelemetry-instrumentation-logging==0.49b0.dev", "opentelemetry-instrumentation-sqlite3==0.49b0.dev", + "opentelemetry-instrumentation-test==1.0.0b.dev", "opentelemetry-instrumentation-threading==0.49b0.dev", "opentelemetry-instrumentation-urllib==0.49b0.dev", "opentelemetry-instrumentation-wsgi==0.49b0.dev", diff --git a/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md b/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md new file mode 100644 index 0000000000..bb0292f819 --- /dev/null +++ b/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## Version 1.0.2 (2024-08-05) + +See [common CHANGELOG](../../CHANGELOG.md) for the changes in this and prior versions. + diff --git a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py index 1a30b96547..12da797c60 100644 --- a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py +++ b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "1.0.2" +__version__ = "1.1.0.dev" diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py index fac29d773f..3e15120575 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.1.5" +__version__ = "0.2.0.dev" diff --git a/scripts/build_a_package.sh b/scripts/build_a_package.sh index 333deccd80..e5642dbd09 100755 --- a/scripts/build_a_package.sh +++ b/scripts/build_a_package.sh @@ -14,23 +14,27 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This script builds wheels for a single package when triggered from a push to -# a tag as part of a GitHub workflow (See .github/publish-a-package.yml). The -# wheel is then published to PyPI. +# This script builds wheels for a single package when triggered from per-package release +# GitHub workflow (see .github/package-release.yml). +# The wheel is then published to PyPI by the workflow. set -ev -if [ -z $GITHUB_REF ]; then - echo 'Failed to run script, missing workflow env variable GITHUB_REF.' +if [ $PACKAGE_NAME ]; then + pkg_name=${PACKAGE_NAME} + pkg_version=${VERSION} +elif [ $GITHUB_REF ]; then + pkg_name_and_version=${GITHUB_REF#refs/tags/*} + pkg_name=${pkg_name_and_version%==*} + pkg_version=${pkg_name_and_version#opentelemetry-*==} +else + echo 'Failed to run script, missing workflow env variable GITHUB_REF or PACKAGE_NAME and VERSION.' exit 1 fi -pkg_name_and_version=${GITHUB_REF#refs/tags/*} -pkg_name=${pkg_name_and_version%==*} -pkg_version=${pkg_name_and_version#opentelemetry-*==} # Get the latest versions of packaging tools -python3 -m pip install --upgrade pip setuptools wheel packaging +python3 -m pip install --upgrade pip build setuptools wheel packaging # Validate version against PEP 440 conventions: https://packaging.pypa.io/en/latest/version.html python3 -c "from packaging.version import Version; Version('${pkg_version}')" @@ -57,7 +61,12 @@ python3 -m build --outdir ${distdir} cd $distdir -pkg_tar_gz_file=${pkg_name}-${pkg_version}.tar.gz +pkg_tar_gz_file=`echo $pkg_name | sed 's/-/_/g'`-${pkg_version}.tar.gz + +echo "Checking if $pkg_tar_gz_file exists in dist/ directory." + +# print the list of files in current directory +echo "$(ls)" if ! [ -f $pkg_tar_gz_file ]; then echo 'Error! Tag version does not match version built using latest package files.' diff --git a/scripts/eachdist.py b/scripts/eachdist.py index 2eaabee2c7..57d98206b7 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -260,7 +260,23 @@ def setup_instparser(instparser): See description of exec for available options.""" ), ) + versionparser.add_argument( + "--package", + "-p", + required=False, + help="Name of a specific package to get the version for", + ) + findparser = subparsers.add_parser( + "find-package", help="Find package path.", + ) + findparser.set_defaults(func=find_package_args) + findparser.add_argument( + "--package", + "-p", + required=True, + help="Name of the package to find", + ) return parser.parse_args(args) @@ -478,7 +494,7 @@ def install_args(args): ), ) ) - + if args.with_dev_deps: rootpath = find_projectroot() runsubprocess( @@ -726,8 +742,37 @@ def format_args(args): def version_args(args): cfg = ConfigParser() cfg.read(str(find_projectroot() / "eachdist.ini")) - print(cfg[args.mode]["version"]) + if not args.package: + print(cfg[args.mode]["version"]) + return + + root = find_projectroot() + for package in find_targets_unordered(root): + if args.package == package.name: + version_file = find("version.py", package) + if version_file is None: + print(f"file missing: {package}/version.py") + return + with open(version_file, encoding="utf-8") as file: + for line in file: + if "__version__" in line: + print(line.split('"')[1]) + return + + print("package not found") + sys.exit(1) + +def find_package_args(args): + root = find_projectroot() + for package in find_targets_unordered(root): + if args.package == package.name: + relative_path = package.relative_to(root) + print(relative_path) + return + + print("package not found") + sys.exit(1) def main(): args = parse_args() diff --git a/scripts/generate_release_notes.sh b/scripts/generate_release_notes.sh new file mode 100755 index 0000000000..193e624174 --- /dev/null +++ b/scripts/generate_release_notes.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# This script copies release notes for the current version from CHANGELOG.md file +# and stores them in /tmp/release-notes.txt. +# It also stores them in a /tmp/CHANGELOG_SECTION.md which is used later to copy them over to the +# CHANGELOG in main branch which is done by merge_changelog_to_main script. + +# This script is called from the release workflows (package-release.yml and release.yml). + +set -ev + +# conditional block not indented because of the heredoc +if [[ ! -z $PRIOR_VERSION_WHEN_PATCH ]]; then +cat > /tmp/release-notes.txt << EOF +This is a patch release on the previous $PRIOR_VERSION_WHEN_PATCH release, fixing the issue(s) below. + +EOF +fi + +# CHANGELOG_SECTION.md is also used at the end of the release workflow +# for copying the change log updates to main +sed -n "0,/^## Version ${VERSION}/d;/^## Version /q;p" $CHANGELOG > /tmp/CHANGELOG_SECTION.md + +# the complex perl regex is needed because markdown docs render newlines as soft wraps +# while release notes render them as line breaks +perl -0pe 's/(?> /tmp/release-notes.txt diff --git a/scripts/merge_changelog_to_main.sh b/scripts/merge_changelog_to_main.sh new file mode 100755 index 0000000000..ee7d027c97 --- /dev/null +++ b/scripts/merge_changelog_to_main.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# This script copies release notes for the current version from CHANGELOG.md file +# and stores them in a temporary file for later use in the release workflow + +# This script is called from the release workflows (package-release.yml and release.yml). + +set -ev + +if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then + # this was not a patch release, so the version exists already in the CHANGELOG.md + + # update the release date + date=$(gh release view $RELEASE_TAG --json publishedAt --jq .publishedAt | sed 's/T.*//') + sed -Ei "s/## Version ${VERSION}.*/## Version ${VERSION} ($date)/" ${CHANGELOG} + + # the entries are copied over from the release branch to support workflows + # where change log entries may be updated after preparing the release branch + + # copy the portion above the release, up to and including the heading + sed -n "0,/^## Version ${VERSION} ($date)/p" ${CHANGELOG} > /tmp/CHANGELOG.md + + # copy the release notes + cat /tmp/CHANGELOG_SECTION.md >> /tmp/CHANGELOG.md + + # copy the portion below the release + sed -n "0,/^## Version ${VERSION} /d;0,/^## Version /{/^## Version/!d};p" ${CHANGELOG} \ + >> /tmp/CHANGELOG.md + + # update the real CHANGELOG.md + cp /tmp/CHANGELOG.md ${CHANGELOG} +else + # this was a patch release, so the version does not exist already in the CHANGELOG.md + + # copy the portion above the top-most release, not including the heading + sed -n "0,/^## Version /{ /^## Version /!p }" ${CHANGELOG} > /tmp/CHANGELOG.md + + # add the heading + date=$(gh release view $RELEASE_TAG --json publishedAt --jq .publishedAt | sed 's/T.*//') + echo "## Version ${VERSION} ($date)" >> /tmp/CHANGELOG.md + + # copy the release notes + cat /tmp/CHANGELOG_SECTION.md >> /tmp/CHANGELOG.md + + # copy the portion starting from the top-most release + sed -n "/^## Version /,\$p" ${CHANGELOG} >> /tmp/CHANGELOG.md + + # update the real CHANGELOG.md + cp /tmp/CHANGELOG.md ${CHANGELOG} +fi \ No newline at end of file diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md new file mode 100644 index 0000000000..2d01260554 --- /dev/null +++ b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## Version 2.0.2 (2024-08-05) + +See [common CHANGELOG](../../CHANGELOG.md) for the changes in this and prior versions. + diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py index c9cb3877e2..b065755302 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.0.2" +__version__ = "2.1.0.dev" From d7d7e96ce5b3948c482296553cd2e63284cd0efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:38:03 -0300 Subject: [PATCH 194/335] fix: shellcheck and docker-tests in CI (#2905) --- .../src/generate_workflows_lib/misc.yml.j2 | 2 -- .github/workflows/misc_0.yml | 5 +++++ .../opentelemetry-docker-tests/tests/check_availability.py | 6 +++--- .../tests/sqlalchemy_tests/test_mssql.py | 5 +++-- tox.ini | 2 ++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index 87f726b587..a3fdadf7a3 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -46,13 +46,11 @@ jobs: - name: Checkout pull request run: git checkout ${% raw %}{{ github.event.pull_request.head.sha }}{% endraw %} {%- endif %} - {%- if job_data != "shellcheck" %} - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: "3.10" - {%- endif %} - name: Install tox run: pip install tox diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 3c3f7bfacf..edb96b60d1 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -122,6 +122,11 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Install tox run: pip install tox diff --git a/tests/opentelemetry-docker-tests/tests/check_availability.py b/tests/opentelemetry-docker-tests/tests/check_availability.py index f9cd5b998e..4eed135e58 100644 --- a/tests/opentelemetry-docker-tests/tests/check_availability.py +++ b/tests/opentelemetry-docker-tests/tests/check_availability.py @@ -112,9 +112,9 @@ def check_redis_connection(): def new_mssql_connection() -> pyodbc.Connection: connection = pyodbc.connect( - f"DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={MSSQL_HOST}," - f"{MSSQL_PORT};DATABASE=master;UID={MSSQL_USER};" - f"PWD={MSSQL_PASSWORD}", + f"DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={MSSQL_HOST}," + f"{MSSQL_PORT};DATABASE=master;UID={MSSQL_USER};TrustServerCertificate=yes;" + f"PWD={MSSQL_PASSWORD};", autocommit=True, ) return connection diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py index 713be24198..b92228c5cd 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py @@ -28,7 +28,8 @@ "user": os.getenv("TEST_MSSQL_USER", "sa"), "password": os.getenv("TEST_MSSQL_PASSWORD", "yourStrong(!)Password"), "database": os.getenv("TEST_MSSQL_DATABASE", "opentelemetry-tests"), - "driver": os.getenv("TEST_MSSQL_DRIVER", "ODBC+Driver+17+for+SQL+Server"), + "driver": os.getenv("TEST_MSSQL_DRIVER", "ODBC+Driver+18+for+SQL+Server"), + "trusted_connection": os.getenv("TEST_MSSQL_TRUSTED_CONNECTION", "yes"), } @@ -40,7 +41,7 @@ class MssqlConnectorTestCase(SQLAlchemyTestMixin): VENDOR = "mssql" SQL_DB = "opentelemetry-tests" ENGINE_ARGS = { - "url": "mssql+pyodbc://%(user)s:%(password)s@%(host)s:%(port)s/%(database)s?driver=%(driver)s" + "url": "mssql+pyodbc://%(user)s:%(password)s@%(host)s:%(port)s/%(database)s?driver=%(driver)s&TrustServerCertificate=%(trusted_connection)s" % MSSQL_CONFIG } diff --git a/tox.ini b/tox.ini index 2b0995d8fc..5bf05d451f 100644 --- a/tox.ini +++ b/tox.ini @@ -1286,6 +1286,8 @@ changedir = tests/opentelemetry-docker-tests/tests commands_pre = + sh -c "sudo apt update -y && sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev unixodbc" + python -c "import pyodbc; print(pyodbc.drivers())" pip install {env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api \ {env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions \ {env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk \ From e4ece57a8136310ed379c04fa77c6b6f8d009bbc Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Sat, 19 Oct 2024 15:49:08 +0200 Subject: [PATCH 195/335] Remove pkg resources (#2871) --- CHANGELOG.md | 8 +- .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-3.txt | 1 - .../test-requirements.txt | 1 - .../tests/test_aiohttp_client_integration.py | 8 +- .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-3.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements.txt | 1 - .../tests/test_fastapi_instrumentation.py | 77 ++++++++++--------- .../pyproject.toml | 1 - .../instrumentation/flask/__init__.py | 4 +- .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-ng.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements-2.txt | 1 - .../test-requirements-3.txt | 1 - .../test-requirements-4.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../tests/__init__.py | 23 ------ .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements-0.txt | 1 - .../test-requirements-1.txt | 1 - .../test-requirements.txt | 1 - .../tests/__init__.py | 23 ------ opentelemetry-distro/test-requirements.txt | 1 - opentelemetry-distro/tests/test_distro.py | 10 ++- opentelemetry-instrumentation/pyproject.toml | 2 +- .../auto_instrumentation/__init__.py | 7 +- .../auto_instrumentation/_load.py | 43 +++++++++-- .../instrumentation/bootstrap.py | 23 +++--- .../instrumentation/dependencies.py | 77 ++++++++++++------- .../opentelemetry/instrumentation/distro.py | 3 +- .../test-requirements.txt | 1 - .../tests/auto_instrumentation/test_load.py | 53 ++++++++++--- .../tests/test_dependencies.py | 42 ++++++---- .../tests/test_distro.py | 17 ++-- .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - .../test-requirements.txt | 1 - tox.ini | 1 - .../test-requirements.txt | 1 - 101 files changed, 245 insertions(+), 260 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94b6c22af8..775043035f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,12 +25,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aiokafka` Wrap `AIOKafkaConsumer.getone()` instead of `AIOKafkaConsumer.__anext__` ([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874)) +### Breaking changes + +- Deprecation of pkg_resource in favor of importlib.metadata + ([#2871](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2871)) + ## Version 1.27.0/0.48b0 (2024-08-28) ### Added -- `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng - inside kafka-python's instrumentation +- `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation ([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537)) - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi` Add ability to disable internal HTTP send and receive spans ([#2802](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2802)) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 318e1e68d5..20d42eb4c6 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -6,7 +6,6 @@ cramjam==2.1.0; platform_python_implementation == "PyPy" cramjam==2.8.1; platform_python_implementation != "PyPy" Deprecated==1.2.14 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index a63c91d0d8..fb9ccfdb7e 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 flaky==3.7.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 markdown-it-py==3.0.0 mdurl==0.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index 26c7046817..c2847c672c 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -3,7 +3,6 @@ aiormq==6.2.3 asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index fac907831a..7c12b25ea4 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -3,7 +3,6 @@ aiormq==6.6.4 asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index ad807173e8..3a4c21b3f7 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -3,7 +3,6 @@ aiormq==6.7.1 asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index 766cc6cf86..f5b8fdf345 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -3,7 +3,6 @@ aiormq==6.8.0 asgiref==3.8.1 Deprecated==1.2.14 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index f4da0edc25..8a0c88f805 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -11,7 +11,6 @@ Flask==3.0.2 frozenlist==1.4.1 http_server_mock==1.7 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 8474bd436f..9ebb180de1 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -24,7 +24,6 @@ import aiohttp.test_utils import yarl from http_server_mock import HttpServerMock -from pkg_resources import iter_entry_points from opentelemetry import trace as trace_api from opentelemetry.instrumentation import aiohttp_client @@ -47,6 +46,7 @@ from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.trace import Span, StatusCode +from opentelemetry.util._importlib_metadata import entry_points def run_with_test_server( @@ -886,9 +886,9 @@ def response_hook( class TestLoadingAioHttpInstrumentor(unittest.TestCase): def test_loading_instrumentor(self): - entry_points = iter_entry_points( - "opentelemetry_instrumentor", "aiohttp-client" + (entry_point,) = entry_points( + group="opentelemetry_instrumentor", name="aiohttp-client" ) - instrumentor = next(entry_points).load()() + instrumentor = entry_point.load()() self.assertIsInstance(instrumentor, AioHttpClientInstrumentor) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index d84eccb649..d492daf3c6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -5,7 +5,6 @@ async-timeout==4.0.3 Deprecated==1.2.14 frozenlist==1.4.1 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index df527586f7..58669a50f9 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -2,7 +2,6 @@ aiopg==1.4.0 asgiref==3.8.1 async-timeout==4.0.3 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index de88049226..4b87261ffb 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index 190e1cbe02..4f1877dd43 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index bb41329e66..c1a45c5887 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 async-timeout==4.0.3 asyncpg==0.29.0 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index a80527dd36..75c3a56b62 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt index 41c228a1fe..bde6a42031 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt @@ -9,7 +9,6 @@ cryptography==43.0.1 Deprecated==1.2.14 docker==7.0.0 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.4 jmespath==1.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index dfa17c79a7..5adcd8ad15 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 boto3==1.34.44 botocore==1.34.44 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 jmespath==1.0.1 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index e5e698c1cf..5253cf3bba 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -9,7 +9,6 @@ cryptography==43.0.1 Deprecated==1.2.14 docker==7.0.0 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.4 jmespath==1.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index 25bf51f2a5..3105aae550 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -4,7 +4,6 @@ pyasyncore==1.0.4 # for python 3.13 (should removed when cassandra-driver repla click==8.1.7 Deprecated==1.2.14 geomet==0.2.1.post1 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index 1e018aae6e..811d805642 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -8,7 +8,6 @@ click-didyoumean==0.3.0 click-plugins==1.1.1 click-repl==0.3.0 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 kombu==5.3.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index c7d494aceb..5ef9e5750a 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -7,7 +7,6 @@ click-didyoumean==0.3.0 click-plugins==1.1.1 click-repl==0.3.0 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 kombu==5.3.5 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 7f389a12af..88b5bbe680 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 confluent-kafka==2.4.0 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index 1275616d45..a05fd86be5 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index 6c1b8337a4..f2375911d3 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 Django==2.2.28 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index 357fd273f5..12f934acd4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 Django==3.2.25 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 1d15b1336b..1ee4b0bfbf 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 backports.zoneinfo==0.2.1 Deprecated==1.2.14 Django==4.2.15 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index fa483e5ade..aba0b28fa2 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 Django==4.2.15 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index 977a440c85..7507078f84 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 Deprecated==1.2.14 elasticsearch==6.8.2 elasticsearch-dsl==6.4.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index 44451736c8..fcd68f1c8e 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 Deprecated==1.2.14 elasticsearch==7.17.9 elasticsearch-dsl==7.4.1 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index a02a9c0270..05af6f4d6c 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -3,7 +3,6 @@ Deprecated==1.2.14 elasticsearch==8.13.1 elasticsearch-dsl==8.13.1 elastic-transport==8.13.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index 11a84eef70..7b0ce1caf9 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 falcon==1.4.1 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index 9d646f3bbb..51f09a4c46 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 falcon==2.0.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index d2a921eb87..cff1244cd0 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 falcon==3.1.1 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 0417301559..0aab3a13e4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -10,7 +10,6 @@ h11==0.14.0 httpcore==1.0.4 httpx==0.27.0 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index b8a6ef010e..bde91ccfcf 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -22,7 +22,6 @@ from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware from fastapi.responses import JSONResponse from fastapi.testclient import TestClient -from pkg_resources import DistributionNotFound, iter_entry_points import opentelemetry.instrumentation.fastapi as otel_fastapi from opentelemetry import trace @@ -55,6 +54,10 @@ from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.globals_test import reset_trace_globals from opentelemetry.test.test_base import TestBase +from opentelemetry.util._importlib_metadata import ( + PackageNotFoundError, + entry_points, +) from opentelemetry.util.http import ( OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, @@ -1028,16 +1031,24 @@ def client_response_hook(send_span, scope, message): ) -def get_distribution_with_fastapi(*args, **kwargs): - dist = args[0] - if dist == "fastapi~=0.58": - # Value does not matter. Only whether an exception is thrown - return None - raise DistributionNotFound() +def mock_version_with_fastapi(*args, **kwargs): + req_name = args[0] + if req_name == "fastapi": + # TODO: Value now matters + return "0.58" + raise PackageNotFoundError() + + +def mock_version_with_old_fastapi(*args, **kwargs): + req_name = args[0] + if req_name == "fastapi": + # TODO: Value now matters + return "0.57" + raise PackageNotFoundError() -def get_distribution_without_fastapi(*args, **kwargs): - raise DistributionNotFound() +def mock_version_without_fastapi(*args, **kwargs): + raise PackageNotFoundError() class TestAutoInstrumentation(TestBaseAutoFastAPI): @@ -1048,43 +1059,37 @@ class TestAutoInstrumentation(TestBaseAutoFastAPI): """ def test_entry_point_exists(self): - eps = iter_entry_points("opentelemetry_instrumentor") - ep = next(eps) - self.assertEqual(ep.dist.key, "opentelemetry-instrumentation-fastapi") - self.assertEqual( - ep.module_name, "opentelemetry.instrumentation.fastapi" - ) - self.assertEqual(ep.attrs, ("FastAPIInstrumentor",)) + (ep,) = entry_points(group="opentelemetry_instrumentor") self.assertEqual(ep.name, "fastapi") - self.assertIsNone(next(eps, None)) - @patch("opentelemetry.instrumentation.dependencies.get_distribution") - def test_instruments_with_fastapi_installed(self, mock_get_distribution): - mock_get_distribution.side_effect = get_distribution_with_fastapi + @patch("opentelemetry.instrumentation.dependencies.version") + def test_instruments_with_fastapi_installed(self, mock_version): + mock_version.side_effect = mock_version_with_fastapi mock_distro = Mock() _load_instrumentors(mock_distro) - mock_get_distribution.assert_called_once_with("fastapi~=0.58") + mock_version.assert_called_once_with("fastapi") self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 1) - args = mock_distro.load_instrumentor.call_args.args - ep = args[0] - self.assertEqual(ep.dist.key, "opentelemetry-instrumentation-fastapi") - self.assertEqual( - ep.module_name, "opentelemetry.instrumentation.fastapi" - ) - self.assertEqual(ep.attrs, ("FastAPIInstrumentor",)) + (ep,) = mock_distro.load_instrumentor.call_args.args self.assertEqual(ep.name, "fastapi") - @patch("opentelemetry.instrumentation.dependencies.get_distribution") + @patch("opentelemetry.instrumentation.dependencies.version") + def test_instruments_with_old_fastapi_installed( + self, mock_version + ): # pylint: disable=no-self-use + mock_version.side_effect = mock_version_with_old_fastapi + mock_distro = Mock() + _load_instrumentors(mock_distro) + mock_version.assert_called_once_with("fastapi") + mock_distro.load_instrumentor.assert_not_called() + + @patch("opentelemetry.instrumentation.dependencies.version") def test_instruments_without_fastapi_installed( - self, mock_get_distribution - ): - mock_get_distribution.side_effect = get_distribution_without_fastapi + self, mock_version + ): # pylint: disable=no-self-use + mock_version.side_effect = mock_version_without_fastapi mock_distro = Mock() _load_instrumentors(mock_distro) - mock_get_distribution.assert_called_once_with("fastapi~=0.58") - with self.assertRaises(DistributionNotFound): - mock_get_distribution("fastapi~=0.58") - self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 0) + mock_version.assert_called_once_with("fastapi") mock_distro.load_instrumentor.assert_not_called() def _create_app(self): diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 0e74ca331f..8d02775824 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -31,7 +31,6 @@ dependencies = [ "opentelemetry-semantic-conventions == 0.49b0.dev", "opentelemetry-util-http == 0.49b0.dev", "packaging >= 21.0", - "importlib-metadata >= 4.0", ] [project.optional-dependencies] 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 192e044655..761fa3660f 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -245,7 +245,6 @@ def response_hook(span: Span, status: str, response_headers: List): from typing import Collection import flask -import importlib_metadata as metadata from packaging import version as package_version import opentelemetry.instrumentation.wsgi as otel_wsgi @@ -272,6 +271,7 @@ def response_hook(span: Span, status: str, response_headers: List): HTTP_SERVER_REQUEST_DURATION, ) from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.util._importlib_metadata import version from opentelemetry.util.http import ( get_excluded_urls, parse_excluded_urls, @@ -288,7 +288,7 @@ def response_hook(span: Span, status: str, response_headers: List): _excluded_urls_from_env = get_excluded_urls("FLASK") -flask_version = metadata.version("flask") +flask_version = version("flask") if package_version.parse(flask_version) >= package_version.parse("2.2.0"): diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index e6fa669267..d1c4687d83 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 click==8.1.7 Deprecated==1.2.14 Flask==2.1.3 -importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index ecd3f680d8..37812de57e 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 click==8.1.7 Deprecated==1.2.14 Flask==2.2.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index da044a29e9..59edf6f540 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -3,7 +3,6 @@ blinker==1.7.0 click==8.1.7 Deprecated==1.2.14 Flask==3.0.2 -importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt index cdea5fca4b..3e688b45c2 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 grpcio==1.62.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index 9b2d088da3..7618e99dfa 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 grpcio==1.63.0 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index 34eac9d10c..b663f4566b 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -7,7 +7,6 @@ h11==0.12.0 httpcore==0.13.7 httpx==0.18.2 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index 93b4d024cb..4cd365d964 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -7,7 +7,6 @@ h11==0.14.0 httpcore==1.0.4 httpx==0.27.0 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index c7a30b8eb5..ffc92e3ffd 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 Jinja2==3.1.4 MarkupSafe==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt index 05e169a7e3..83cef19c4f 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 kafka-python-ng==2.2.2 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index a042ce833e..87752e3542 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 kafka-python==2.0.2 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index 600d066cc1..2512824c23 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt index 22e61d9df3..45fb95cb37 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 mysql-connector-python==8.3.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt index 1a58c16a05..0ca8efb64c 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 mysql-connector-python==9.0.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index 3dfa1b161d..0abcd23bd2 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 mysqlclient==2.2.4 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index 871d4feac1..3e2f26b098 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pika==0.13.1 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index b1c9e9094f..9ad521943f 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pika==1.3.2 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index 93ea09ca15..a68ae0b797 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 backports.zoneinfo==0.2.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index 096d31599a..f45e3be149 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index 5ae59dc5ea..482c30222d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index 25e0f03bd6..d1b214c595 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index 3005dc7aa8..64224bc7a5 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index 4c259345c6..d54b48ffea 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index b0e2147639..509bdda5a6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index 36d0164961..93e1c041d5 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index a9319d5fdb..1e8a49d67d 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 dnspython==2.6.1 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index b1496da4e6..02018b0c5e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 423838f23e..97815133f8 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 hupper==1.12.1 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 PasteDeploy==3.1.0 diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 4690006ef1..6beac4a9cc 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -2,7 +2,6 @@ asgiref==3.8.1 async-timeout==4.0.3 Deprecated==1.2.14 fakeredis==2.23.3 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index a299e145a1..bfa53ed1f8 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index a201206f0f..0b8d7ada10 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -4,7 +4,6 @@ charset-normalizer==3.3.2 Deprecated==1.2.14 httpretty==1.1.4 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index cccdc3cb63..e3f87916c2 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 cffi==1.17.0 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index b275f4e30e..885cee8c62 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -2,7 +2,6 @@ aiosqlite==0.20.0 asgiref==3.8.1 Deprecated==1.2.14 greenlet==3.0.3 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index 2469d354d3..c6d1cb28e2 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt index 7f46b46981..3d756aa52e 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt @@ -8,7 +8,6 @@ h11==0.14.0 httpcore==1.0.4 httpx==0.27.0 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index 710e4bdf7f..4b9b45b63d 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt index 743026e94a..e8f9e579c6 100644 --- a/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py index a0b2062b52..e69de29bb2 100644 --- a/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py @@ -1,23 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import pkg_resources - -# IMPORTANT: Only the TEst module needs this because it is always the first -# package that uses the `{rootdir}/*/tests/` path and gets installed by -# `eachdist.py` and according to `eachdist.ini`. - -# Naming the tests module as a namespace package ensures that -# relative imports will resolve properly for subsequent test packages, -# as it enables searching for a composite of multiple test modules. -pkg_resources.declare_namespace(__name__) diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index 84c3bb4d29..b40c591b6d 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 209c07e523..56a088ec62 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -7,7 +7,6 @@ Deprecated==1.2.14 Flask==3.0.2 http_server_mock==1.7 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.4 diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index 4ec6d195bf..c00ed195af 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -2,7 +2,6 @@ aiosqlite==0.17.0 annotated-types==0.7.0 asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 iso8601==1.1.0 packaging==24.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index 998ca77f6a..11fc627895 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 httpretty==1.1.4 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index ad29eb1263..d85ac17f4f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 httpretty==1.1.4 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 48406b222d..14da384548 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 httpretty==1.1.4 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index acabba1abf..433d9e3201 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py index 8a3124243a..e69de29bb2 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py @@ -1,23 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import pkg_resources - -# IMPORTANT: Only the wsgi module needs this because it is always the first -# package that uses the `{rootdir}/*/tests/` path and gets installed by -# `eachdist.py` and according to `eachdist.ini`. - -# Naming the tests module as a namespace package ensures that -# relative imports will resolve properly for subsequent test packages, -# as it enables searching for a composite of multiple test modules. -pkg_resources.declare_namespace(__name__) diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index 4f63e9e7b6..dba17daec3 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/opentelemetry-distro/tests/test_distro.py b/opentelemetry-distro/tests/test_distro.py index ea7b9f08c8..9cd89eb039 100644 --- a/opentelemetry-distro/tests/test_distro.py +++ b/opentelemetry-distro/tests/test_distro.py @@ -16,21 +16,23 @@ import os from unittest import TestCase, mock -from pkg_resources import DistributionNotFound, require - from opentelemetry.distro import OpenTelemetryDistro from opentelemetry.environment_variables import ( OTEL_METRICS_EXPORTER, OTEL_TRACES_EXPORTER, ) from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_PROTOCOL +from opentelemetry.util._importlib_metadata import ( + PackageNotFoundError, + version, +) class TestDistribution(TestCase): def test_package_available(self): try: - require(["opentelemetry-distro"]) - except DistributionNotFound: + version("opentelemetry-distro") + except PackageNotFoundError: self.fail("opentelemetry-distro not installed") @mock.patch.dict("os.environ", {}, clear=True) diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index 866b9b5008..2bdfd1dbe6 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.4", "opentelemetry-semantic-conventions >= 0.48b0", - "setuptools >= 16.0", "wrapt >= 1.0.0, < 2.0.0", + "packaging >= 18.0", ] [project.scripts] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py index a09334432d..963b3a6956 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py @@ -19,9 +19,8 @@ from re import sub from shutil import which -from pkg_resources import iter_entry_points - from opentelemetry.instrumentation.version import __version__ +from opentelemetry.util._importlib_metadata import entry_points _logger = getLogger(__name__) @@ -48,8 +47,8 @@ def run() -> None: argument_otel_environment_variable = {} - for entry_point in iter_entry_points( - "opentelemetry_environment_variables" + for entry_point in entry_points( + group="opentelemetry_environment_variables" ): environment_variable_module = entry_point.load() diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py index 27b57da3ef..7154238bb7 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +from functools import cached_property from logging import getLogger from os import environ -from pkg_resources import iter_entry_points - from opentelemetry.instrumentation.dependencies import ( get_dist_dependency_conflicts, ) @@ -27,13 +26,39 @@ OTEL_PYTHON_DISTRO, ) from opentelemetry.instrumentation.version import __version__ +from opentelemetry.util._importlib_metadata import ( + EntryPoint, + distributions, + entry_points, +) _logger = getLogger(__name__) +class _EntryPointDistFinder: + @cached_property + def _mapping(self): + return { + self._key_for(ep): dist + for dist in distributions() + for ep in dist.entry_points + } + + def dist_for(self, entry_point: EntryPoint): + dist = getattr(entry_point, "dist", None) + if dist: + return dist + + return self._mapping.get(self._key_for(entry_point)) + + @staticmethod + def _key_for(entry_point: EntryPoint): + return f"{entry_point.group}:{entry_point.name}:{entry_point.value}" + + def _load_distro() -> BaseDistro: distro_name = environ.get(OTEL_PYTHON_DISTRO, None) - for entry_point in iter_entry_points("opentelemetry_distro"): + for entry_point in entry_points(group="opentelemetry_distro"): try: # If no distro is specified, use first to come up. if distro_name is None or distro_name == entry_point.name: @@ -58,15 +83,16 @@ def _load_distro() -> BaseDistro: def _load_instrumentors(distro): package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, []) + entry_point_finder = _EntryPointDistFinder() if isinstance(package_to_exclude, str): package_to_exclude = package_to_exclude.split(",") # to handle users entering "requests , flask" or "requests, flask" with spaces package_to_exclude = [x.strip() for x in package_to_exclude] - for entry_point in iter_entry_points("opentelemetry_pre_instrument"): + for entry_point in entry_points(group="opentelemetry_pre_instrument"): entry_point.load()() - for entry_point in iter_entry_points("opentelemetry_instrumentor"): + for entry_point in entry_points(group="opentelemetry_instrumentor"): if entry_point.name in package_to_exclude: _logger.debug( "Instrumentation skipped for library %s", entry_point.name @@ -74,7 +100,8 @@ def _load_instrumentors(distro): continue try: - conflict = get_dist_dependency_conflicts(entry_point.dist) + entry_point_dist = entry_point_finder.dist_for(entry_point) + conflict = get_dist_dependency_conflicts(entry_point_dist) if conflict: _logger.debug( "Skipping instrumentation %s: %s", @@ -90,14 +117,14 @@ def _load_instrumentors(distro): _logger.exception("Instrumenting of %s failed", entry_point.name) raise exc - for entry_point in iter_entry_points("opentelemetry_post_instrument"): + for entry_point in entry_points(group="opentelemetry_post_instrument"): entry_point.load()() def _load_configurators(): configurator_name = environ.get(OTEL_PYTHON_CONFIGURATOR, None) configured = None - for entry_point in iter_entry_points("opentelemetry_configurator"): + for entry_point in entry_points(group="opentelemetry_configurator"): if configured is not None: _logger.warning( "Configuration of %s not loaded, %s already loaded", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index 1cc28abca4..02926ea5c4 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -23,13 +23,17 @@ check_call, ) -import pkg_resources +from packaging.requirements import Requirement from opentelemetry.instrumentation.bootstrap_gen import ( default_instrumentations, libraries, ) from opentelemetry.instrumentation.version import __version__ +from opentelemetry.util._importlib_metadata import ( + PackageNotFoundError, + version, +) logger = logging.getLogger(__name__) @@ -91,18 +95,19 @@ def _pip_check(): def _is_installed(req): - if req in sys.modules: - return True + req = Requirement(req) try: - pkg_resources.get_distribution(req) - except pkg_resources.DistributionNotFound: + dist_version = version(req.name) + except PackageNotFoundError: return False - except pkg_resources.VersionConflict as exc: + + if not req.specifier.filter(dist_version): logger.warning( - "instrumentation for package %s is available but version %s is installed. Skipping.", - exc.req, - exc.dist.as_requirement(), # pylint: disable=no-member + "instrumentation for package %s is available" + " but version %s is installed. Skipping.", + req, + dist_version, ) return False return True diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py index 2da0a3d18b..7ebc88d647 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py @@ -1,12 +1,26 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from logging import getLogger -from typing import Collection, Optional +from typing import Collection, Optional, Union + +from packaging.requirements import InvalidRequirement, Requirement -from pkg_resources import ( +from opentelemetry.util._importlib_metadata import ( Distribution, - DistributionNotFound, - RequirementParseError, - VersionConflict, - get_distribution, + PackageNotFoundError, + version, ) logger = getLogger(__name__) @@ -27,36 +41,43 @@ def __str__(self): def get_dist_dependency_conflicts( dist: Distribution, ) -> Optional[DependencyConflict]: - main_deps = dist.requires() instrumentation_deps = [] - for dep in dist.requires(("instruments",)): - if dep not in main_deps: - # we set marker to none so string representation of the dependency looks like - # requests ~= 1.0 - # instead of - # requests ~= 1.0; extra = "instruments" - # which does not work with `get_distribution()` - dep.marker = None - instrumentation_deps.append(str(dep)) + extra = "extra" + instruments = "instruments" + instruments_marker = {extra: instruments} + for dep in dist.requires: + if extra not in dep or instruments not in dep: + continue + + req = Requirement(dep) + if req.marker.evaluate(instruments_marker): + instrumentation_deps.append(req) return get_dependency_conflicts(instrumentation_deps) def get_dependency_conflicts( - deps: Collection[str], + deps: Collection[Union[str, Requirement]], ) -> Optional[DependencyConflict]: for dep in deps: + if isinstance(dep, Requirement): + req = dep + else: + try: + req = Requirement(dep) + except InvalidRequirement as exc: + logger.warning( + 'error parsing dependency, reporting as a conflict: "%s" - %s', + dep, + exc, + ) + return DependencyConflict(dep) + try: - get_distribution(dep) - except VersionConflict as exc: - return DependencyConflict(dep, exc.dist) - except DistributionNotFound: - return DependencyConflict(dep) - except RequirementParseError as exc: - logger.warning( - 'error parsing dependency, reporting as a conflict: "%s" - %s', - dep, - exc, - ) + dist_version = version(req.name) + except PackageNotFoundError: return DependencyConflict(dep) + + if not req.specifier.contains(dist_version): + return DependencyConflict(dep, f"{req.name} {dist_version}") return None diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py index 93646bbb2f..1bc847f988 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py @@ -20,9 +20,8 @@ from abc import ABC, abstractmethod from logging import getLogger -from pkg_resources import EntryPoint - from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.util._importlib_metadata import EntryPoint _LOG = getLogger(__name__) diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index 24a5a56daf..943a45c8f4 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py index 5fc59b542d..98bad3d9f9 100644 --- a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py +++ b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py @@ -23,6 +23,7 @@ OTEL_PYTHON_DISTRO, ) from opentelemetry.instrumentation.version import __version__ +from opentelemetry.util._importlib_metadata import EntryPoint, entry_points class TestLoad(TestCase): @@ -30,7 +31,7 @@ class TestLoad(TestCase): "os.environ", {OTEL_PYTHON_CONFIGURATOR: "custom_configurator2"} ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_configurators( self, iter_mock @@ -61,7 +62,7 @@ def test_load_configurators( "os.environ", {OTEL_PYTHON_CONFIGURATOR: "custom_configurator2"} ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_configurators_no_ep( self, iter_mock @@ -74,7 +75,7 @@ def test_load_configurators_no_ep( "os.environ", {OTEL_PYTHON_CONFIGURATOR: "custom_configurator2"} ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_configurators_error(self, iter_mock): # Add multiple entry points but only specify the 2nd in the environment variable. @@ -101,7 +102,7 @@ def test_load_configurators_error(self, iter_mock): "opentelemetry.instrumentation.auto_instrumentation._load.isinstance" ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_distro(self, iter_mock, isinstance_mock): # Add multiple entry points but only specify the 2nd in the environment variable. @@ -134,7 +135,7 @@ def test_load_distro(self, iter_mock, isinstance_mock): "opentelemetry.instrumentation.auto_instrumentation._load.DefaultDistro" ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_distro_not_distro( self, iter_mock, default_distro_mock, isinstance_mock @@ -166,7 +167,7 @@ def test_load_distro_not_distro( "opentelemetry.instrumentation.auto_instrumentation._load.DefaultDistro" ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_distro_no_ep(self, iter_mock, default_distro_mock): iter_mock.return_value = () @@ -181,7 +182,7 @@ def test_load_distro_no_ep(self, iter_mock, default_distro_mock): "opentelemetry.instrumentation.auto_instrumentation._load.isinstance" ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_distro_error(self, iter_mock, isinstance_mock): ep_mock1 = Mock() @@ -211,7 +212,7 @@ def test_load_distro_error(self, iter_mock, isinstance_mock): "opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts" ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_instrumentors(self, iter_mock, dep_mock): # Mock opentelemetry_pre_instrument entry points @@ -285,7 +286,7 @@ def test_load_instrumentors(self, iter_mock, dep_mock): "opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts" ) @patch( - "opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points" + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) def test_load_instrumentors_dep_conflict( self, iter_mock, dep_mock @@ -314,3 +315,37 @@ def test_load_instrumentors_dep_conflict( ] ) distro_mock.load_instrumentor.assert_called_once() + + def test_load_instrumentors_no_entry_point_mocks(self): + distro_mock = Mock() + _load._load_instrumentors(distro_mock) + # this has no specific assert because it is run for every instrumentation + self.assertTrue(distro_mock) + + def test_entry_point_dist_finder(self): + entry_point_finder = _load._EntryPointDistFinder() + self.assertTrue(entry_point_finder._mapping) + entry_point = list( + entry_points(group="opentelemetry_environment_variables") + )[0] + self.assertTrue(entry_point) + self.assertTrue(entry_point.dist) + + # this will not hit cache + entry_point_dist = entry_point_finder.dist_for(entry_point) + self.assertTrue(entry_point_dist) + # dist are not comparable so we are sure we are not hitting the cache + self.assertEqual(entry_point.dist, entry_point_dist) + + # this will hit cache + entry_point_without_dist = EntryPoint( + name=entry_point.name, + group=entry_point.group, + value=entry_point.value, + ) + self.assertIsNone(entry_point_without_dist.dist) + new_entry_point_dist = entry_point_finder.dist_for( + entry_point_without_dist + ) + # dist are not comparable, being truthy is enough + self.assertTrue(new_entry_point_dist) diff --git a/opentelemetry-instrumentation/tests/test_dependencies.py b/opentelemetry-instrumentation/tests/test_dependencies.py index 04bcf476ea..bdee0f6f01 100644 --- a/opentelemetry-instrumentation/tests/test_dependencies.py +++ b/opentelemetry-instrumentation/tests/test_dependencies.py @@ -14,8 +14,8 @@ # pylint: disable=protected-access -import pkg_resources import pytest +from packaging.requirements import Requirement from opentelemetry.instrumentation.dependencies import ( DependencyConflict, @@ -23,15 +23,30 @@ get_dist_dependency_conflicts, ) from opentelemetry.test.test_base import TestBase +from opentelemetry.util._importlib_metadata import Distribution class TestDependencyConflicts(TestBase): def test_get_dependency_conflicts_empty(self): self.assertIsNone(get_dependency_conflicts([])) + def test_get_dependency_conflicts_no_conflict_requirement(self): + req = Requirement("pytest") + self.assertIsNone(get_dependency_conflicts([req])) + def test_get_dependency_conflicts_no_conflict(self): self.assertIsNone(get_dependency_conflicts(["pytest"])) + def test_get_dependency_conflicts_not_installed_requirement(self): + req = Requirement("this-package-does-not-exist") + conflict = get_dependency_conflicts([req]) + self.assertTrue(conflict is not None) + self.assertTrue(isinstance(conflict, DependencyConflict)) + self.assertEqual( + str(conflict), + 'DependencyConflict: requested: "this-package-does-not-exist" but found: "None"', + ) + def test_get_dependency_conflicts_not_installed(self): conflict = get_dependency_conflicts(["this-package-does-not-exist"]) self.assertTrue(conflict is not None) @@ -51,24 +66,23 @@ def test_get_dependency_conflicts_mismatched_version(self): ) def test_get_dist_dependency_conflicts(self): - def mock_requires(extras=()): - if "instruments" in extras: - return [ - pkg_resources.Requirement( - 'test-pkg ~= 1.0; extra == "instruments"' - ) - ] - return [] + class MockDistribution(Distribution): + def locate_file(self, path): + pass - dist = pkg_resources.Distribution( - project_name="test-instrumentation", version="1.0" - ) - dist.requires = mock_requires + def read_text(self, filename): + pass + + @property + def requires(self): + return ['test-pkg ~= 1.0; extra == "instruments"'] + + dist = MockDistribution() conflict = get_dist_dependency_conflicts(dist) self.assertTrue(conflict is not None) self.assertTrue(isinstance(conflict, DependencyConflict)) self.assertEqual( str(conflict), - 'DependencyConflict: requested: "test-pkg~=1.0" but found: "None"', + 'DependencyConflict: requested: "test-pkg~=1.0; extra == "instruments"" but found: "None"', ) diff --git a/opentelemetry-instrumentation/tests/test_distro.py b/opentelemetry-instrumentation/tests/test_distro.py index 399b3f8a65..03a95614df 100644 --- a/opentelemetry-instrumentation/tests/test_distro.py +++ b/opentelemetry-instrumentation/tests/test_distro.py @@ -15,10 +15,9 @@ from unittest import TestCase -from pkg_resources import EntryPoint - from opentelemetry.instrumentation.distro import BaseDistro from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.util._importlib_metadata import EntryPoint class MockInstrumetor(BaseInstrumentor): @@ -33,11 +32,13 @@ def _uninstrument(self, **kwargs): class MockEntryPoint(EntryPoint): - def __init__(self, obj): # pylint: disable=super-init-not-called - self._obj = obj + def __init__( + self, name, value, group + ): # pylint: disable=super-init-not-called + pass def load(self, *args, **kwargs): # pylint: disable=signature-differs - return self._obj + return MockInstrumetor class MockDistro(BaseDistro): @@ -51,7 +52,11 @@ def test_load_instrumentor(self): distro = MockDistro() instrumentor = MockInstrumetor() - entry_point = MockEntryPoint(MockInstrumetor) + entry_point = MockEntryPoint( + "MockInstrumetor", + value="opentelemetry", + group="opentelemetry_distro", + ) self.assertFalse(instrumentor._is_instrumented_by_opentelemetry) distro.load_instrumentor(entry_point) diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt index 8f5b428ba4..6cbca62382 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt @@ -3,7 +3,6 @@ certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 idna==3.7 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index 4a97065065..379c534e26 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements.txt b/resource/opentelemetry-resource-detector-azure/test-requirements.txt index fe04c99490..353546f670 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/resource/opentelemetry-resource-detector-container/test-requirements.txt b/resource/opentelemetry-resource-detector-container/test-requirements.txt index 7cf0d49001..859005d42b 100644 --- a/resource/opentelemetry-resource-detector-container/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-container/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt index 3b44b54a61..91a69c8d15 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/tox.ini b/tox.ini index 5bf05d451f..cec851872e 100644 --- a/tox.ini +++ b/tox.ini @@ -1234,7 +1234,6 @@ deps = greenlet==3.0.3 grpcio==1.62.1 idna==2.10 - importlib-metadata==6.11.0 iniconfig==2.0.0 jsonschema==3.2.0 kombu==5.3.5 diff --git a/util/opentelemetry-util-http/test-requirements.txt b/util/opentelemetry-util-http/test-requirements.txt index 7c71ae2ef3..ea2448bab9 100644 --- a/util/opentelemetry-util-http/test-requirements.txt +++ b/util/opentelemetry-util-http/test-requirements.txt @@ -1,6 +1,5 @@ asgiref==3.8.1 Deprecated==1.2.14 -importlib-metadata==6.11.0 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 From cef28d6f24e06c5161da911458c171201ab0fd31 Mon Sep 17 00:00:00 2001 From: Allen Kim Date: Tue, 22 Oct 2024 17:22:07 +0900 Subject: [PATCH 196/335] Fix to allow topic to be passed via kwargs (#2901) * Fix to allow topic to be imported from kwargs * add changelog * lint * separate assert function --- CHANGELOG.md | 2 ++ .../instrumentation/confluent_kafka/__init__.py | 4 +++- .../instrumentation/confluent_kafka/utils.py | 6 ++---- .../tests/test_instrumentation.py | 15 +++++++++++++++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 775043035f..075f1c0a57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aiokafka` Wrap `AIOKafkaConsumer.getone()` instead of `AIOKafkaConsumer.__anext__` ([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874)) +- `opentelemetry-instrumentation-confluent-kafka` Fix to allow `topic` to be extracted from `kwargs` in `produce()` + ([#2901])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2901) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index 3d1cc79c93..95a14627b3 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -363,7 +363,9 @@ def wrap_produce(func, instance, tracer, args, kwargs): headers = [] kwargs["headers"] = headers - topic = KafkaPropertiesExtractor.extract_produce_topic(args) + topic = KafkaPropertiesExtractor.extract_produce_topic( + args, kwargs + ) _enrich_span( span, topic, diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py index 4769f2a88f..60dc13e675 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py @@ -25,11 +25,9 @@ def _extract_argument(key, position, default_value, args, kwargs): return kwargs.get(key, default_value) @staticmethod - def extract_produce_topic(args): + def extract_produce_topic(args, kwargs): """extract topic from `produce` method arguments in Producer class""" - if len(args) > 0: - return args[0] - return "unknown" + return kwargs.get("topic") or (args[0] if args else "unknown") @staticmethod def extract_produce_headers(args, kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py index 27653d6777..986116900d 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py @@ -284,6 +284,15 @@ def _compare_spans(self, spans, expected_spans): expected_attribute_value, span.attributes[attribute_key] ) + def _assert_topic(self, span, expected_topic: str) -> None: + self.assertEqual( + span.attributes[SpanAttributes.MESSAGING_DESTINATION], + expected_topic, + ) + + def _assert_span_count(self, span_list, expected_count: int) -> None: + self.assertEqual(len(span_list), expected_count) + def test_producer_poll(self) -> None: instrumentation = ConfluentKafkaInstrumentor() message_queue = [] @@ -299,6 +308,9 @@ def test_producer_poll(self) -> None: producer.produce(topic="topic-1", key="key-1", value="value-1") msg = producer.poll() self.assertIsNotNone(msg) + span_list = self.memory_exporter.get_finished_spans() + self._assert_span_count(span_list, 1) + self._assert_topic(span_list[0], "topic-1") def test_producer_flush(self) -> None: instrumentation = ConfluentKafkaInstrumentor() @@ -315,3 +327,6 @@ def test_producer_flush(self) -> None: producer.produce(topic="topic-1", key="key-1", value="value-1") msg = producer.flush() self.assertIsNotNone(msg) + span_list = self.memory_exporter.get_finished_spans() + self._assert_span_count(span_list, 1) + self._assert_topic(span_list[0], "topic-1") From beed0aa395b8b4b3c341c4030bf99102e2046e9b Mon Sep 17 00:00:00 2001 From: Karthik Kalyanaraman <105607645+karthikscale3@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:21:43 -0700 Subject: [PATCH 197/335] Add Initial Support for Instrumenting OpenAI Python Library - Chat Completion Create (#2759) --- .github/workflows/lint_0.yml | 18 + .github/workflows/test_0.yml | 216 ++++++------ .github/workflows/test_1.yml | 108 ++++++ CHANGELOG.md | 66 ++-- eachdist.ini | 1 + instrumentation/README.md | 1 + .../LICENSE | 201 +++++++++++ .../README.rst | 26 ++ .../pyproject.toml | 54 +++ .../instrumentation/openai_v2/__init__.py | 80 +++++ .../instrumentation/openai_v2/package.py | 16 + .../instrumentation/openai_v2/patch.py | 316 ++++++++++++++++++ .../instrumentation/openai_v2/utils.py | 165 +++++++++ .../instrumentation/openai_v2/version.py | 15 + .../test-requirements.txt | 11 + .../tests/__init__.py | 0 .../tests/cassettes/test_chat_completion.yaml | 92 +++++ .../test_chat_completion_streaming.yaml | 113 +++++++ .../tests/conftest.py | 70 ++++ .../tests/test_chat_completions.py | 157 +++++++++ .../pyproject.toml | 1 + .../instrumentation/bootstrap_gen.py | 4 + tox.ini | 16 + 23 files changed, 1617 insertions(+), 130 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/LICENSE create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/pyproject.toml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index 2236dc422c..1fd3198785 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -16,6 +16,24 @@ env: jobs: + lint-instrumentation-openai-v2: + name: instrumentation-openai-v2 + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-openai-v2 + lint-resource-detector-container: name: resource-detector-container runs-on: ubuntu-latest diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index d251737227..df74e90021 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -16,6 +16,114 @@ env: jobs: + py38-test-instrumentation-openai-v2_ubuntu-latest: + name: instrumentation-openai-v2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-openai-v2 -- -ra + + py39-test-instrumentation-openai-v2_ubuntu-latest: + name: instrumentation-openai-v2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-openai-v2 -- -ra + + py310-test-instrumentation-openai-v2_ubuntu-latest: + name: instrumentation-openai-v2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-openai-v2 -- -ra + + py311-test-instrumentation-openai-v2_ubuntu-latest: + name: instrumentation-openai-v2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-openai-v2 -- -ra + + py312-test-instrumentation-openai-v2_ubuntu-latest: + name: instrumentation-openai-v2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-openai-v2 -- -ra + + pypy3-test-instrumentation-openai-v2_ubuntu-latest: + name: instrumentation-openai-v2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-openai-v2 -- -ra + py38-test-resource-detector-container_ubuntu-latest: name: resource-detector-container 3.8 Ubuntu runs-on: ubuntu-latest @@ -4407,111 +4515,3 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra - - py311-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra - - py311-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra - - py312-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra - - py312-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra - - py312-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra - - py312-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 30ca4e67d2..30e02c5634 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,114 @@ env: jobs: + py311-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra + + py311-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra + + py312-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra + + py312-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra + + py312-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + + py312-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra + py312-test-instrumentation-pymemcache-4_ubuntu-latest: name: instrumentation-pymemcache-4 3.12 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 075f1c0a57..3308c2a2ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 1.27.0/0.49b0 () + +### Added + +- `opentelemetry-instrumentation-openai-v2` Instrumentation for OpenAI >= 0.27.0 + ([#2759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2759)) + ### Added - `opentelemetry-instrumentation-fastapi` Add autoinstrumentation mechanism tests. @@ -236,7 +243,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2420](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2420)) - `opentelemetry-instrumentation-elasticsearch` Disabling instrumentation with native OTel support enabled ([#2524](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2524)) -- `opentelemetry-instrumentation-asyncio` Check for __name__ attribute in the coroutine +- `opentelemetry-instrumentation-asyncio` Check for **name** attribute in the coroutine ([#2521](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2521)) - `opentelemetry-instrumentation-requests` Fix wrong time unit for duration histogram ([#2553](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2553)) @@ -251,6 +258,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2146](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2146)) ### Fixed + - `opentelemetry-instrumentation-celery` Allow Celery instrumentation to be installed multiple times ([#2342](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2342)) - Align gRPC span status codes to OTEL specification @@ -268,8 +276,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - AwsLambdaInstrumentor sets `cloud.account.id` span attribute ([#2367](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2367)) - ### Added + - `opentelemetry-instrumentation-fastapi` Add support for configuring header extraction via runtime constructor parameters ([#2241](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2241)) @@ -280,7 +288,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-resource-detector-azure` Added 10s timeout to VM Resource Detector ([#2119](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2119)) - `opentelemetry-instrumentation-asyncpg` Allow AsyncPGInstrumentor to be instantiated multiple times -([#1791](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1791)) + ([#1791](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1791)) - `opentelemetry-instrumentation-confluent-kafka` Add support for higher versions until 2.3.0 of confluent_kafka ([#2132](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2132)) - `opentelemetry-resource-detector-azure` Changed timeout to 4 seconds due to [timeout bug](https://github.com/open-telemetry/opentelemetry-python/issues/3644) @@ -364,6 +372,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#152](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2013)) ## Version 1.19.0/0.40b0 (2023-07-13) + - `opentelemetry-instrumentation-asgi` Add `http.server.request.size` metric ([#1867](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1867)) @@ -410,6 +419,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1823)) ### Added + - `opentelemetry-instrumentation-kafka-python` Add instrumentation to `consume` method ([#1786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1786)) @@ -460,6 +470,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1692](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1692)) ### Changed + - Update HTTP server/client instrumentation span names to comply with spec ([#1759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1759)) @@ -497,7 +508,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Support `aio_pika` 9.x (([#1670](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1670]) -- `opentelemetry-instrumentation-redis` Add `sanitize_query` config option to allow query sanitization. ([#1572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1572)) +- `opentelemetry-instrumentation-redis` Add `sanitize_query` config option to allow query sanitization. ([#1572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1572)) - `opentelemetry-instrumentation-elasticsearch` Add optional db.statement query sanitization. ([#1598](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1598)) - `opentelemetry-instrumentation-celery` Record exceptions as events on the span. @@ -521,7 +532,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1575](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1575)) - Fix SQLAlchemy uninstrumentation ([#1581](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1581)) -- `opentelemetry-instrumentation-grpc` Fix code()/details() of _OpentelemetryServicerContext. +- `opentelemetry-instrumentation-grpc` Fix code()/details() of \_OpentelemetryServicerContext. ([#1578](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1578)) - Fix aiopg instrumentation to work with aiopg < 2.0.0 ([#1473](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1473)) @@ -573,7 +584,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1430](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1430)) - `opentelemetry-instrumentation-aiohttp-client` Allow overriding of status in response hook. ([#1394](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1394)) -- `opentelemetry-instrumentation-pymysql` Fix dbapi connection instrument wrapper has no _sock member. +- `opentelemetry-instrumentation-pymysql` Fix dbapi connection instrument wrapper has no \_sock member. ([#1424](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1424)) - `opentelemetry-instrumentation-dbapi` Fix the check for the connection already being instrumented in instrument_connection(). ([#1424](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1424)) @@ -658,7 +669,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add metric instrumentation in starlette ([#1327](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1327)) - ### Fixed - `opentelemetry-instrumentation-kafka-python`: wait for metadata @@ -671,7 +681,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1208](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1208)) - `opentelemetry-instrumentation-aiohttp-client` Fix producing additional spans with each newly created ClientSession - ([#1246](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1246)) -- Add _is_opentelemetry_instrumented check in _InstrumentedFastAPI class +- Add \_is_opentelemetry_instrumented check in \_InstrumentedFastAPI class ([#1313](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1313)) - Fix uninstrumentation of existing app instances in FastAPI ([#1258](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1258)) @@ -690,6 +700,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1203](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1203)) ### Added + - `opentelemetry-instrumentation-redis` add support to instrument RedisCluster clients ([#1177](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1177)) - `opentelemetry-instrumentation-sqlalchemy` Added span for the connection phase ([#1133](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1133)) @@ -702,11 +713,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.12.0rc2-0.32b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.12.0rc2-0.32b0) - 2022-07-01 - - Pyramid: Only categorize 500s server exceptions as errors ([#1037](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1037)) ### Fixed + - Fix bug in system metrics by checking their configuration ([#1129](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1129)) - Adding escape call to fix [auto-instrumentation not producing spans on Windows](https://github.com/open-telemetry/opentelemetry-python/issues/2703). @@ -719,8 +730,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fixed typo in `system.network.io` metric configuration ([#1135](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1135)) - ### Added + - `opentelemetry-instrumentation-aiohttp-client` Add support for optional custom trace_configs argument. ([1079](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1079)) - `opentelemetry-instrumentation-sqlalchemy` add support to instrument multiple engines @@ -744,10 +755,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Integrated sqlcommenter plugin into opentelemetry-instrumentation-django ([#896](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/896)) - ## Version 1.12.0rc1/0.31b0 (2022-05-17) ### Fixed + - `opentelemetry-instrumentation-aiohttp-client` make span attributes available to sampler ([#1072](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1072)) - `opentelemetry-instrumentation-aws-lambda` Fixed an issue - in some rare cases (API GW proxy integration test) @@ -760,6 +771,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-sdk-extension-aws` change timeout for AWS EC2 and EKS metadata requests from 1000 seconds and 2000 seconds to 1 second ### Added + - `opentelemetry-instrument` and `opentelemetry-bootstrap` now include a `--version` flag ([#1065](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1065)) - `opentelemetry-instrumentation-redis` now instruments asynchronous Redis clients, if the installed redis-py includes async support (>=4.2.0). @@ -767,22 +779,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-boto3sqs` added AWS's SQS instrumentation. ([#1081](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1081)) - ## Version 1.11.1/0.30b1 (2022-04-21) ### Added + - `opentelemetry-instrumentation-starlette` Capture custom request/response headers in span attributes ([#1046](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1046)) ### Fixed + - Prune autoinstrumentation sitecustomize module directory from PYTHONPATH immediately ([#1066](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1066)) - ## Version 1.11.0/0.30b0 (2022-04-18) ### Fixed -- `opentelemetry-instrumentation-pyramid` Fixed which package is the correct caller in _traced_init. + +- `opentelemetry-instrumentation-pyramid` Fixed which package is the correct caller in \_traced_init. ([#830](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/830)) - `opentelemetry-instrumentation-tornado` Fix Tornado errors mapping to 500 ([#1048](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1048)) @@ -816,7 +829,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-pyramid` Pyramid: Capture custom request/response headers in span attributes ([#1022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1022)) - ## Version 1.10.0/0.29b0 (2022-03-10) - `opentelemetry-instrumentation-wsgi` Capture custom request/response headers in span attributes @@ -830,7 +842,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aws-lambda` `SpanKind.SERVER` by default, add more cases for `SpanKind.CONSUMER` services. ([#926](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/926)) - `opentelemetry-instrumentation-sqlalchemy` added experimental sql commenter capability - ([#924](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/924)) + ([#924](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/924)) - `opentelemetry-contrib-instrumentations` added new meta-package that installs all contrib instrumentations. ([#681](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/681)) - `opentelemetry-instrumentation-dbapi` add experimental sql commenter capability @@ -869,12 +881,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Version 1.9.0/0.28b0 (2022-01-26) - ### Added - `opentelemetry-instrumentation-pyramid` Pyramid: Conditionally create SERVER spans ([#869](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/869)) -- `opentelemetry-instrumentation-grpc` added `trailing_metadata` to _OpenTelemetryServicerContext. +- `opentelemetry-instrumentation-grpc` added `trailing_metadata` to \_OpenTelemetryServicerContext. ([#871](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/871)) - `opentelemetry-instrumentation-asgi` now returns a `traceresponse` response header. ([#817](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/817)) @@ -908,12 +919,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aiohttp-client` aiohttp: Remove `span_name` from docs ([#857](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/857)) - ## Version 1.8.0/0.27b0 (2021-12-17) ### Added -- `opentelemetry-instrumentation-aws-lambda` Adds support for configurable flush timeout via `OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT` property. ([#825](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/825)) +- `opentelemetry-instrumentation-aws-lambda` Adds support for configurable flush timeout via `OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT` property. ([#825](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/825)) - `opentelemetry-instrumentation-pika` Adds support for versions between `0.12.0` to `1.0.0`. ([#837](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/837)) ### Fixed @@ -983,13 +993,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#755](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/755)) ### Added + - `opentelemetry-instrumentation-pika` Add `publish_hook` and `consume_hook` callbacks passed as arguments to the instrument method ([#763](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/763)) - ## Version 1.6.1/0.25b1 (2021-10-18) ### Changed + - `opentelemetry-util-http` no longer contains an instrumentation entrypoint and will not be loaded automatically by the auto instrumentor. ([#745](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/745)) @@ -1003,7 +1014,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#760](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/760)) ## Version 1.6.0/0.25b0 (2021-10-13) + ### Added + - `opentelemetry-sdk-extension-aws` Release AWS Python SDK Extension as 1.0.0 ([#667](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/667)) - `opentelemetry-instrumentation-urllib3`, `opentelemetry-instrumentation-requests` @@ -1030,6 +1043,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#391](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/391)) ### Changed + - `opentelemetry-instrumentation-flask` Fix `RuntimeError: Working outside of request context` ([#734](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/734)) - `opentelemetry-propagators-aws-xray` Rename `AwsXRayFormat` to `AwsXRayPropagator` @@ -1060,6 +1074,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Version 1.5.0/0.24b0 (2021-08-26) ### Added + - `opentelemetry-sdk-extension-aws` Add AWS resource detectors to extension package ([#586](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/586)) - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-aiohttp-client`, `openetelemetry-instrumentation-fastapi`, @@ -1078,10 +1093,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Version 1.4.0/0.23b0 (2021-07-21) ### Removed + - Move `opentelemetry-instrumentation` to the core repo. ([#595](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/595)) ### Changed + - `opentelemetry-instrumentation-falcon` added support for Falcon 3. ([#607](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/607)) - `opentelemetry-instrumentation-tornado` properly instrument work done in tornado on_finish method. @@ -1129,12 +1146,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#568](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/568)) ### Added + - `opentelemetry-instrumentation-httpx` Add `httpx` instrumentation ([#461](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/461)) ## Version 1.3.0/0.22b0 (2021-06-01) ### Changed + - `opentelemetry-bootstrap` not longer forcibly removes and re-installs libraries and their instrumentations. This means running bootstrap will not auto-upgrade existing dependencies and as a result not cause dependency conflicts. @@ -1151,6 +1170,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#488](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/488)) ### Added + - `opentelemetry-instrumentation-botocore` now supports context propagation for lambda invoke via Payload embedded headers. ([#458](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/458)) @@ -1160,6 +1180,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Version 1.2.0/0.21b0 (2021-05-11) ### Changed + - Instrumentation packages don't specify the libraries they instrument as dependencies anymore. Instead, they verify the correct version of libraries are installed at runtime. ([#475](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/475)) @@ -1711,6 +1732,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-ext-http-requests` Updates for core library changes - `Added support for PyPy3` Initial release + ## [#1033](https://github.com/open-telemetryopentelemetry-python-contrib/issues/1033) ## Version 0.1a0 (2019-09-30) @@ -1725,7 +1747,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-resource-detector-azure` Added 10s timeout to VM Resource Detector ([#2119](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2119)) - `opentelemetry-instrumentation-asyncpg` Allow AsyncPGInstrumentor to be instantiated multiple times -([#1791](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1791)) + ([#1791](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1791)) - `opentelemetry-instrumentation-confluent-kafka` Add support for higher versions until 2.3.0 of confluent_kafka ([#2132](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2132)) - `opentelemetry-resource-detector-azure` Changed timeout to 4 seconds due to [timeout bug](https://github.com/open-telemetry/opentelemetry-python/issues/3644) diff --git a/eachdist.ini b/eachdist.ini index 950b751685..c04fb571ce 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -50,6 +50,7 @@ packages= opentelemetry-resource-detector-azure opentelemetry-sdk-extension-aws opentelemetry-propagator-aws-xray + opentelemetry-instrumentation-openai-v2 opentelemetry-instrumentation-test [lintroots] diff --git a/instrumentation/README.md b/instrumentation/README.md index 6bb47f6f9c..db437fe518 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -29,6 +29,7 @@ | [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging | No | experimental | [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python >= 8.0, < 10.0 | No | experimental | [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | experimental +| [opentelemetry-instrumentation-openai-v2](./opentelemetry-instrumentation-openai-v2) | openai >= 1.26.0 | No | experimental | [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 | No | experimental | [opentelemetry-instrumentation-psycopg](./opentelemetry-instrumentation-psycopg) | psycopg >= 3.1.0 | No | experimental | [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/LICENSE b/instrumentation/opentelemetry-instrumentation-openai-v2/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst new file mode 100644 index 0000000000..cd7e9b3922 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst @@ -0,0 +1,26 @@ +OpenTelemetry OpenAI Instrumentation +==================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-openai-v2.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-openai-v2/ + +Instrumentation with OpenAI that supports the openai library and is +specified to trace_integration using 'OpenAI'. + + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-openai-v2 + + +References +---------- +* `OpenTelemetry OpenAI Instrumentation `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ + diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-openai-v2/pyproject.toml new file mode 100644 index 0000000000..b342cdade7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -0,0 +1,54 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-openai-v2" +dynamic = ["version"] +description = "OpenTelemetry Official OpenAI instrumentation" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.8" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "opentelemetry-api ~= 1.12", + "opentelemetry-instrumentation ~= 0.48b0", + "opentelemetry-semantic-conventions ~= 0.48b0" +] + +[project.optional-dependencies] +instruments = [ + "openai >= 1.0.0", +] + +[project.entry-points.opentelemetry_instrumentor] +openai = "opentelemetry.instrumentation.openai_v2:OpenAIInstrumentor" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-openai-v2" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/openai_v2/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py new file mode 100644 index 0000000000..64f74eaefe --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -0,0 +1,80 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +OpenAI client instrumentation supporting `openai`, it can be enabled by +using ``OpenAIInstrumentor``. + +.. _openai: https://pypi.org/project/openai/ + +Usage +----- + +.. code:: python + + from openai import OpenAI + from opentelemetry.instrumentation.openai import OpenAIInstrumentor + + OpenAIInstrumentor().instrument() + + client = OpenAI() + response = client.chat.completions.create( + model="gpt-4o-mini", + messages=[ + {"role": "user", "content": "Write a short poem on open telemetry."}, + ], + ) + +API +--- +""" + + +from typing import Collection + +from wrapt import wrap_function_wrapper + +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.instrumentation.openai_v2.package import _instruments +from opentelemetry.instrumentation.utils import unwrap +from opentelemetry.semconv.schemas import Schemas +from opentelemetry.trace import get_tracer + +from .patch import chat_completions_create + + +class OpenAIInstrumentor(BaseInstrumentor): + + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs): + """Enable OpenAI instrumentation.""" + tracer_provider = kwargs.get("tracer_provider") + tracer = get_tracer( + __name__, + "", + tracer_provider, + schema_url=Schemas.V1_27_0.value, + ) + wrap_function_wrapper( + module="openai.resources.chat.completions", + name="Completions.create", + wrapper=chat_completions_create(tracer), + ) + + def _uninstrument(self, **kwargs): + import openai + + unwrap(openai.resources.chat.completions.Completions, "create") diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py new file mode 100644 index 0000000000..b53e25f7df --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +_instruments = ("openai >= 1.26.0",) diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py new file mode 100644 index 0000000000..e139a799cb --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -0,0 +1,316 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json + +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.trace import Span, SpanKind, Tracer +from opentelemetry.trace.status import Status, StatusCode + +from .utils import ( + extract_content, + extract_tools_prompt, + get_llm_request_attributes, + is_streaming, + set_event_completion, + set_event_prompt, + set_span_attribute, + silently_fail, +) + + +def chat_completions_create(tracer: Tracer): + """Wrap the `create` method of the `ChatCompletion` class to trace it.""" + + def traced_method(wrapped, instance, args, kwargs): + + llm_prompts = [] + + for item in kwargs.get("messages", []): + tools_prompt = extract_tools_prompt(item) + llm_prompts.append(tools_prompt if tools_prompt else item) + + span_attributes = {**get_llm_request_attributes(kwargs)} + span_name = f"{span_attributes[GenAIAttributes.GEN_AI_OPERATION_NAME]} {span_attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL]}" + + span = tracer.start_span( + name=span_name, kind=SpanKind.CLIENT, attributes=span_attributes + ) + if span.is_recording(): + _set_input_attributes(span, span_attributes) + set_event_prompt(span, json.dumps(llm_prompts)) + + try: + result = wrapped(*args, **kwargs) + if is_streaming(kwargs): + return StreamWrapper( + result, + span, + function_call=kwargs.get("functions") is not None, + tool_calls=kwargs.get("tools") is not None, + ) + else: + if span.is_recording(): + _set_response_attributes(span, result) + span.end() + return result + + except Exception as error: + span.set_status(Status(StatusCode.ERROR, str(error))) + if span.is_recording(): + span.set_attribute( + ErrorAttributes.ERROR_TYPE, type(error).__qualname__ + ) + span.end() + raise + + return traced_method + + +@silently_fail +def _set_input_attributes(span, attributes): + for field, value in attributes.items(): + set_span_attribute(span, field, value) + + +@silently_fail +def _set_response_attributes(span, result): + set_span_attribute( + span, GenAIAttributes.GEN_AI_RESPONSE_MODEL, result.model + ) + if getattr(result, "choices", None): + choices = result.choices + responses = [ + { + "role": ( + choice.message.role + if choice.message and choice.message.role + else "assistant" + ), + "content": extract_content(choice), + **( + { + "content_filter_results": choice[ + "content_filter_results" + ] + } + if "content_filter_results" in choice + else {} + ), + } + for choice in choices + ] + finish_reasons = [] + for choice in choices: + finish_reasons.append(choice.finish_reason or "error") + + set_span_attribute( + span, + GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, + finish_reasons, + ) + set_event_completion(span, responses) + + if getattr(result, "id", None): + set_span_attribute(span, GenAIAttributes.GEN_AI_RESPONSE_ID, result.id) + + # Get the usage + if getattr(result, "usage", None): + set_span_attribute( + span, + GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, + result.usage.prompt_tokens, + ) + set_span_attribute( + span, + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, + result.usage.completion_tokens, + ) + + +class StreamWrapper: + span: Span + response_id: str = "" + response_model: str = "" + + def __init__( + self, + stream, + span, + prompt_tokens=0, + function_call=False, + tool_calls=False, + ): + self.stream = stream + self.span = span + self.prompt_tokens = prompt_tokens + self.function_call = function_call + self.tool_calls = tool_calls + self.result_content = [] + self.completion_tokens = 0 + self._span_started = False + self.setup() + + def setup(self): + if not self._span_started: + self._span_started = True + + def cleanup(self): + if self._span_started: + if self.response_model: + set_span_attribute( + self.span, + GenAIAttributes.GEN_AI_RESPONSE_MODEL, + self.response_model, + ) + + if self.response_id: + set_span_attribute( + self.span, + GenAIAttributes.GEN_AI_RESPONSE_ID, + self.response_id, + ) + + set_span_attribute( + self.span, + GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, + self.prompt_tokens, + ) + set_span_attribute( + self.span, + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, + self.completion_tokens, + ) + set_event_completion( + self.span, + [ + { + "role": "assistant", + "content": "".join(self.result_content), + } + ], + ) + + self.span.end() + self._span_started = False + + def __enter__(self): + self.setup() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + try: + if exc_type is not None: + self.span.set_status(Status(StatusCode.ERROR, str(exc_val))) + self.span.set_attribute( + ErrorAttributes.ERROR_TYPE, exc_type.__qualname__ + ) + finally: + self.cleanup() + return False # Propagate the exception + + def __iter__(self): + return self + + def __next__(self): + try: + chunk = next(self.stream) + self.process_chunk(chunk) + return chunk + except StopIteration: + self.cleanup() + raise + except Exception as error: + self.span.set_status(Status(StatusCode.ERROR, str(error))) + self.span.set_attribute( + ErrorAttributes.ERROR_TYPE, type(error).__qualname__ + ) + self.cleanup() + raise + + def set_response_model(self, chunk): + if self.response_model: + return + + if getattr(chunk, "model", None): + self.response_model = chunk.model + + def set_response_id(self, chunk): + if self.response_id: + return + + if getattr(chunk, "id", None): + self.response_id = chunk.id + + def build_streaming_response(self, chunk): + if getattr(chunk, "choices", None) is None: + return + + choices = chunk.choices + content = [] + if not self.function_call and not self.tool_calls: + for choice in choices: + if choice.delta and choice.delta.content is not None: + content = [choice.delta.content] + + elif self.function_call: + for choice in choices: + if ( + choice.delta + and choice.delta.function_call is not None + and choice.delta.function_call.arguments is not None + ): + content = [choice.delta.function_call.arguments] + + elif self.tool_calls: + for choice in choices: + if choice.delta and choice.delta.tool_calls is not None: + toolcalls = choice.delta.tool_calls + content = [] + for tool_call in toolcalls: + if ( + tool_call + and tool_call.function is not None + and tool_call.function.arguments is not None + ): + content.append(tool_call.function.arguments) + + finish_reasons = [] + for choice in choices: + finish_reasons.append(choice.finish_reason or "error") + + set_span_attribute( + self.span, + GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, + finish_reasons, + ) + if content: + self.result_content.append(content[0]) + + def set_usage(self, chunk): + if getattr(chunk, "usage", None): + self.completion_tokens = chunk.usage.completion_tokens + self.prompt_tokens = chunk.usage.prompt_tokens + + def process_chunk(self, chunk): + self.set_response_id(chunk) + self.set_response_model(chunk) + self.build_streaming_response(chunk) + self.set_usage(chunk) diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py new file mode 100644 index 0000000000..7d0eddc58d --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -0,0 +1,165 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import logging +from typing import Optional, Union + +from openai import NOT_GIVEN + +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) + + +def silently_fail(func): + """ + A decorator that catches exceptions thrown by the decorated function and logs them as warnings. + """ + + logger = logging.getLogger(func.__module__) + + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except Exception as exception: + logger.warning( + "Failed to execute %s, error: %s", + func.__name__, + str(exception), + ) + + return wrapper + + +def extract_content(choice): + if getattr(choice, "message", None) is None: + return "" + + # Check if choice.message exists and has a content attribute + message = choice.message + if getattr(message, "content", None): + return choice.message.content + + # Check if choice.message has tool_calls and extract information accordingly + elif getattr(message, "tool_calls", None): + result = [ + { + "id": tool_call.id, + "type": tool_call.type, + "function": { + "name": tool_call.function.name, + "arguments": tool_call.function.arguments, + }, + } + for tool_call in choice.message.tool_calls + ] + return result + + # Check if choice.message has a function_call and extract information accordingly + elif getattr(message, "function_call", None): + return { + "name": choice.message.function_call.name, + "arguments": choice.message.function_call.arguments, + } + + # Return an empty string if none of the above conditions are met + else: + return "" + + +def extract_tools_prompt(item): + tool_calls = getattr(item, "tool_calls", None) + if tool_calls is None: + return + + calls = [] + for tool_call in tool_calls: + tool_call_dict = { + "id": getattr(tool_call, "id", ""), + "type": getattr(tool_call, "type", ""), + } + + if hasattr(tool_call, "function"): + tool_call_dict["function"] = { + "name": getattr(tool_call.function, "name", ""), + "arguments": getattr(tool_call.function, "arguments", ""), + } + calls.append(tool_call_dict) + return calls + + +def set_event_prompt(span, prompt): + span.add_event( + name="gen_ai.content.prompt", + attributes={ + GenAIAttributes.GEN_AI_PROMPT: prompt, + }, + ) + + +def set_span_attributes(span, attributes: dict): + for field, value in attributes.model_dump(by_alias=True).items(): + set_span_attribute(span, field, value) + + +def set_event_completion(span, result_content): + span.add_event( + name="gen_ai.content.completion", + attributes={ + GenAIAttributes.GEN_AI_COMPLETION: json.dumps(result_content), + }, + ) + + +def set_span_attribute(span, name, value): + if non_numerical_value_is_set(value) is False: + return + + span.set_attribute(name, value) + + +def is_streaming(kwargs): + return non_numerical_value_is_set(kwargs.get("stream")) + + +def non_numerical_value_is_set(value: Optional[Union[bool, str]]): + return bool(value) and value != NOT_GIVEN + + +def get_llm_request_attributes( + kwargs, + operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value, +): + + attributes = { + GenAIAttributes.GEN_AI_OPERATION_NAME: operation_name, + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value, + GenAIAttributes.GEN_AI_REQUEST_MODEL: kwargs.get( + "model", "gpt-3.5-turbo" + ), + GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: kwargs.get("temperature"), + GenAIAttributes.GEN_AI_REQUEST_TOP_P: kwargs.get("p") + or kwargs.get("top_p"), + GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: kwargs.get("max_tokens"), + GenAIAttributes.GEN_AI_REQUEST_PRESENCE_PENALTY: kwargs.get( + "presence_penalty" + ), + GenAIAttributes.GEN_AI_REQUEST_FREQUENCY_PENALTY: kwargs.get( + "frequency_penalty" + ), + } + + # filter out None values + return {k: v for k, v in attributes.items() if v is not None} diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py new file mode 100644 index 0000000000..0e95b73df6 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "2.0.0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt new file mode 100644 index 0000000000..198226dcfa --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt @@ -0,0 +1,11 @@ +openai==1.26.0 +pydantic==2.8.2 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +packaging==24.0 +pytest==7.4.4 +pytest-vcr==1.0.2 +wrapt==1.16.0 + +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-openai-v2 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion.yaml new file mode 100644 index 0000000000..3bfd94e415 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion.yaml @@ -0,0 +1,92 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": + "gpt-4", "stream": false}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '100' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AC6ajKKHHpvf6x2Qm35t6m3QE8qli\",\n \"object\": + \"chat.completion\",\n \"created\": 1727448637,\n \"model\": \"gpt-4-0613\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"This is a test.\",\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 12,\n \"completion_tokens\": + 5,\n \"total_tokens\": 17,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c9c4e9b7fb674d8-PMO + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Fri, 27 Sep 2024 14:50:37 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + content-length: + - '551' + openai-organization: test_organization + openai-processing-ms: + - '434' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '1000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '999977' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 1ms + x-request-id: + - req_5f2690abaf909a9f047488694d44495e + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml new file mode 100644 index 0000000000..c61133739b --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml @@ -0,0 +1,113 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": + "gpt-4", "stream": true, "stream_options": {"include_usage": true}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '142' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: 'data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" + is"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" + a"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" + test"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + + data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"completion_tokens_details":{"reasoning_tokens":0}}} + + + data: [DONE] + + + ' + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c9c4ea489d57948-PMO + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Fri, 27 Sep 2024 14:50:38 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + openai-organization: test_organization + openai-processing-ms: + - '161' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '1000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '999977' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 1ms + x-request-id: + - req_3fa9ac9f3693c712e4c377e26d203e58 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py new file mode 100644 index 0000000000..976d58d7d8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -0,0 +1,70 @@ +"""Unit tests configuration module.""" + +import os + +import pytest +from openai import OpenAI + +from opentelemetry import trace +from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + + +@pytest.fixture(scope="session") +def exporter(): + exporter = InMemorySpanExporter() + processor = SimpleSpanProcessor(exporter) + + provider = TracerProvider() + provider.add_span_processor(processor) + trace.set_tracer_provider(provider) + + return exporter + + +@pytest.fixture(autouse=True) +def clear_exporter(exporter): + exporter.clear() + + +@pytest.fixture(autouse=True) +def environment(): + if not os.getenv("OPENAI_API_KEY"): + os.environ["OPENAI_API_KEY"] = "test-api-key" + + +@pytest.fixture +def openai_client(): + return OpenAI() + + +@pytest.fixture(scope="module") +def vcr_config(): + return { + "filter_headers": ["authorization", "api-key"], + "decode_compressed_response": True, + "before_record_response": scrub_response_headers, + } + + +@pytest.fixture(scope="session", autouse=True) +def instrument(): + OpenAIInstrumentor().instrument() + + +@pytest.fixture(scope="session", autouse=True) +def uninstrument(): + OpenAIInstrumentor().uninstrument() + + +def scrub_response_headers(response): + """ + This scrubs sensitive response headers. Note they are case-sensitive! + """ + response["headers"]["openai-organization"] = "test_organization" + response["headers"]["Set-Cookie"] = "test_set_cookie" + return response diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py new file mode 100644 index 0000000000..2b0f6a7f8c --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -0,0 +1,157 @@ +import json + +import pytest + +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) + + +@pytest.mark.vcr() +def test_chat_completion(exporter, openai_client): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": False, + } + + response = openai_client.chat.completions.create(**kwargs) + spans = exporter.get_finished_spans() + chat_completion_span = spans[0] + # assert that the span name is correct + assert chat_completion_span.name == f"chat {llm_model_value}" + + attributes = chat_completion_span.attributes + operation_name = attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + system = attributes[GenAIAttributes.GEN_AI_SYSTEM] + request_model = attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + response_model = attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + response_id = attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] + input_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + output_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + # assert that the attributes are correct + assert ( + operation_name == GenAIAttributes.GenAiOperationNameValues.CHAT.value + ) + assert system == GenAIAttributes.GenAiSystemValues.OPENAI.value + assert request_model == llm_model_value + assert response_model == response.model + assert response_id == response.id + assert input_tokens == response.usage.prompt_tokens + assert output_tokens == response.usage.completion_tokens + + events = chat_completion_span.events + + # assert that the prompt and completion events are present + prompt_event = list( + filter( + lambda event: event.name == "gen_ai.content.prompt", + events, + ) + ) + completion_event = list( + filter( + lambda event: event.name == "gen_ai.content.completion", + events, + ) + ) + + assert prompt_event + assert completion_event + + # assert that the prompt and completion events have the correct attributes + assert prompt_event[0].attributes[ + GenAIAttributes.GEN_AI_PROMPT + ] == json.dumps(messages_value) + + assert ( + json.loads( + completion_event[0].attributes[GenAIAttributes.GEN_AI_COMPLETION] + )[0]["content"] + == response.choices[0].message.content + ) + + +@pytest.mark.vcr() +def test_chat_completion_streaming(exporter, openai_client): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + "stream_options": {"include_usage": True}, + } + + response_stream_usage = None + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = openai_client.chat.completions.create(**kwargs) + for chunk in response: + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + spans = exporter.get_finished_spans() + streaming_span = spans[0] + + assert streaming_span.name == f"chat {llm_model_value}" + attributes = streaming_span.attributes + + operation_name = attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + system = attributes[GenAIAttributes.GEN_AI_SYSTEM] + request_model = attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + response_model = attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + response_id = attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] + input_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + output_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + assert ( + operation_name == GenAIAttributes.GenAiOperationNameValues.CHAT.value + ) + assert system == GenAIAttributes.GenAiSystemValues.OPENAI.value + assert request_model == llm_model_value + assert response_model == response_stream_model + assert response_id == response_stream_id + assert input_tokens == response_stream_usage.prompt_tokens + assert output_tokens == response_stream_usage.completion_tokens + + events = streaming_span.events + + # assert that the prompt and completion events are present + prompt_event = list( + filter( + lambda event: event.name == "gen_ai.content.prompt", + events, + ) + ) + completion_event = list( + filter( + lambda event: event.name == "gen_ai.content.completion", + events, + ) + ) + + assert prompt_event + assert completion_event + + # assert that the prompt and completion events have the correct attributes + assert prompt_event[0].attributes[ + GenAIAttributes.GEN_AI_PROMPT + ] == json.dumps(messages_value) + + assert ( + json.loads( + completion_event[0].attributes[GenAIAttributes.GEN_AI_COMPLETION] + )[0]["content"] + == response_stream_result + ) diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index b34226b669..2b6b2cfedb 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -57,6 +57,7 @@ dependencies = [ "opentelemetry-instrumentation-logging==0.49b0.dev", "opentelemetry-instrumentation-mysql==0.49b0.dev", "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", + "opentelemetry-instrumentation-openai-v2==2.0.0.dev", "opentelemetry-instrumentation-pika==0.49b0.dev", "opentelemetry-instrumentation-psycopg==0.49b0.dev", "opentelemetry-instrumentation-psycopg2==0.49b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index ff6065d058..95d25026f9 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -120,6 +120,10 @@ "library": "mysqlclient < 3", "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", }, + { + "library": "openai >= 1.0.0", + "instrumentation": "opentelemetry-instrumentation-openai-v2==2.0.0.dev", + }, { "library": "pika >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-pika==0.49b0.dev", diff --git a/tox.ini b/tox.ini index cec851872e..c6bb6a17a4 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,11 @@ envlist = ; Environments are organized by individual package, allowing ; for specifying supported Python versions per package. + ; instrumentation-openai + py3{8,9,10,11,12}-test-instrumentation-openai-v2 + pypy3-test-instrumentation-openai-v2 + lint-instrumentation-openai-v2 + ; opentelemetry-resource-detector-container py3{8,9,10,11,12}-test-resource-detector-container pypy3-test-resource-detector-container @@ -404,6 +409,12 @@ commands_pre = opentelemetry-instrumentation: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils opentelemetry-instrumentation: pip install -r {toxinidir}/opentelemetry-instrumentation/test-requirements.txt + openai: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + openai: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + openai: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + openai: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + openai: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt + distro: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api distro: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions distro: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -456,6 +467,11 @@ commands_pre = kafka-pythonng: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk kafka-pythonng: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt + openai: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + openai: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + openai: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + openai: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt + confluent-kafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api confluent-kafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions confluent-kafka: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk From 9d06509bf58bf39e78714e7fcbdc6f5ee818c948 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 23 Oct 2024 14:32:06 +0200 Subject: [PATCH 198/335] Fixup changelog (#2924) --- CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3308c2a2ca..028b4ee63e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,15 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -## Version 1.27.0/0.49b0 () - ### Added - `opentelemetry-instrumentation-openai-v2` Instrumentation for OpenAI >= 0.27.0 ([#2759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2759)) - -### Added - - `opentelemetry-instrumentation-fastapi` Add autoinstrumentation mechanism tests. ([#2860](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2860)) - `opentelemetry-instrumentation-aiokafka` Add instrumentor and auto instrumentation support for aiokafka From 0adc58b4bfe7ace79909bee925dfa3c3e06e6fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:54:14 -0300 Subject: [PATCH 199/335] Introducing ruff as linter and formatter (basic setup) (#2921) --- .flake8 | 37 ---- .github/workflows/generate_workflows.py | 4 +- .../generate_workflows_lib/hatch_build.py | 10 +- .../src/generate_workflows_lib/__init__.py | 90 +++----- .github/workflows/misc_0.yml | 18 ++ .isort.cfg | 19 -- .pre-commit-config.yaml | 22 +- CONTRIBUTING.md | 13 +- _template/pyproject.toml | 2 +- dev-requirements.txt | 4 +- .../prometheus_remote_write/__init__.py | 4 +- gen-requirements.txt | 3 +- .../aio_pika/aio_pika_instrumentor.py | 2 +- .../instrumentation/aio_pika/span_builder.py | 20 +- .../tests/test_aiohttp_client_integration.py | 1 - .../tests/test_aiohttp_server_integration.py | 1 - .../instrumentation/aiokafka/__init__.py | 1 + .../aiopg/aiopg_integration.py | 2 +- .../instrumentation/aiopg/wrappers.py | 1 + .../instrumentation/asgi/__init__.py | 4 +- .../instrumentation/asyncio/__init__.py | 2 +- .../asyncio/environment_variables.py | 1 + .../tests/test_asyncio_anext.py | 2 +- .../instrumentation/asyncpg/__init__.py | 1 - .../instrumentation/aws_lambda/__init__.py | 2 - .../test_aws_lambda_instrumentation_manual.py | 4 +- .../instrumentation/boto3sqs/__init__.py | 1 + .../botocore/extensions/_messaging.py | 2 +- .../confluent_kafka/__init__.py | 21 +- .../tests/utils.py | 8 +- .../django/middleware/otel_middleware.py | 13 +- .../tests/views.py | 12 +- .../instrumentation/falcon/__init__.py | 8 +- .../tests/test_fastapi_instrumentation.py | 8 +- ..._fastapi_instrumentation_custom_headers.py | 1 - .../instrumentation/flask/__init__.py | 1 + .../instrumentation/grpc/__init__.py | 1 + .../grpc/grpcext/_interceptor.py | 1 - .../instrumentation/httpx/__init__.py | 9 +- .../tests/test_httpx_integration.py | 1 - .../instrumentation/kafka/__init__.py | 1 + .../instrumentation/logging/__init__.py | 2 +- .../instrumentation/logging/constants.py | 4 +- .../tests/test_logging.py | 4 +- .../instrumentation/openai_v2/__init__.py | 2 - .../instrumentation/openai_v2/patch.py | 1 - .../instrumentation/openai_v2/utils.py | 1 - .../instrumentation/psycopg/__init__.py | 6 +- .../tests/test_pymemcache.py | 4 +- .../instrumentation/pymongo/__init__.py | 1 + .../instrumentation/pyramid/__init__.py | 1 + .../instrumentation/redis/__init__.py | 1 + .../instrumentation/redis/util.py | 1 + .../instrumentation/remoulade/__init__.py | 1 + .../instrumentation/sqlalchemy/__init__.py | 1 + .../instrumentation/starlette/__init__.py | 1 + .../instrumentation/tornado/__init__.py | 1 - .../instrumentation/tortoiseorm/__init__.py | 1 + .../instrumentation/urllib/__init__.py | 5 +- .../tests/test_metrics_instrumentation.py | 3 - .../instrumentation/urllib3/__init__.py | 2 - .../tests/test_wsgi_middleware.py | 6 +- .../auto_instrumentation/_load.py | 4 +- .../opentelemetry/instrumentation/distro.py | 1 - .../tests/auto_instrumentation/test_load.py | 12 +- .../tests/auto_instrumentation/test_run.py | 4 +- .../tests/test_distro.py | 4 +- .../propagators/aws/aws_xray_propagator.py | 1 - .../tests/test_aws_xray_lambda_propagator.py | 6 - pyproject.toml | 50 ++++- scripts/eachdist.py | 57 ++--- .../tests/redis/test_redis_functional.py | 58 +++--- tox.ini | 197 +----------------- 73 files changed, 269 insertions(+), 532 deletions(-) delete mode 100644 .flake8 delete mode 100644 .isort.cfg diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 5683cfc1f3..0000000000 --- a/.flake8 +++ /dev/null @@ -1,37 +0,0 @@ -[flake8] -ignore = - # line too long, defer to black - E501 - - # allow line breaks before binary ops - W503 - - # allow line breaks after binary ops - W504 - - # allow whitespace before ':' (https://github.com/psf/black#slices) - E203 - - # conflicts with black - E701 - E704 - -exclude = - .bzr - .git - .hg - .svn - .tox - CVS - .venv*/ - venv*/ - target - __pycache__ - exporter/opentelemetry-exporter-jaeger/src/opentelemetry/exporter/jaeger/gen/ - exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/gen/ - exporter/opentelemetry-exporter-jaeger/build/* - docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/grpc/gen/ - docs/examples/opentelemetry-example-app/build/* - opentelemetry-proto/build/* - opentelemetry-proto/src/opentelemetry/proto/ - scripts/* diff --git a/.github/workflows/generate_workflows.py b/.github/workflows/generate_workflows.py index dbd128bc43..bda8eee827 100644 --- a/.github/workflows/generate_workflows.py +++ b/.github/workflows/generate_workflows.py @@ -1,9 +1,9 @@ from pathlib import Path from generate_workflows_lib import ( - generate_test_workflow, generate_lint_workflow, - generate_misc_workflow + generate_misc_workflow, + generate_test_workflow, ) tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") diff --git a/.github/workflows/generate_workflows_lib/hatch_build.py b/.github/workflows/generate_workflows_lib/hatch_build.py index aedf360a35..aff625f20e 100644 --- a/.github/workflows/generate_workflows_lib/hatch_build.py +++ b/.github/workflows/generate_workflows_lib/hatch_build.py @@ -1,15 +1,17 @@ -from hatchling.builders.hooks.plugin.interface import BuildHookInterface from pathlib import Path +from hatchling.builders.hooks.plugin.interface import BuildHookInterface -class CustomBuildHook(BuildHookInterface): +class CustomBuildHook(BuildHookInterface): def initialize(self, version, build_data): - with open( Path(__file__).parent.parent.parent.parent.joinpath("tox.ini") ) as tox_ini_file_0: with open( - Path(__file__).parent.joinpath("src/generate_workflows_lib/tox.ini"), "w" + Path(__file__).parent.joinpath( + "src/generate_workflows_lib/tox.ini" + ), + "w", ) as tox_ini_file_1: tox_ini_file_1.write(tox_ini_file_0.read()) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index 31f11062c4..0308fbe5f3 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -1,12 +1,12 @@ +from collections import defaultdict +from pathlib import Path from re import compile as re_compile + from jinja2 import Environment, FileSystemLoader -from pathlib import Path from tox.config.cli.parse import get_options -from tox.session.state import State from tox.config.sets import CoreConfigSet from tox.config.source.tox_ini import ToxIni -from collections import defaultdict - +from tox.session.state import State _tox_test_env_regex = re_compile( r"(?Ppy\w+)-test-" @@ -19,27 +19,23 @@ def get_tox_envs(tox_ini_path: Path) -> list: - tox_ini = ToxIni(tox_ini_path) conf = State(get_options(), []).conf tox_section = next(tox_ini.sections()) - core_config_set = ( - CoreConfigSet(conf, tox_section, tox_ini_path.parent, tox_ini_path) + core_config_set = CoreConfigSet( + conf, tox_section, tox_ini_path.parent, tox_ini_path ) ( - core_config_set. - loaders. - extend( - tox_ini. - get_loaders( + core_config_set.loaders.extend( + tox_ini.get_loaders( tox_section, base=[], override_map=defaultdict(list, {}), - conf=core_config_set + conf=core_config_set, ) ) ) @@ -48,11 +44,7 @@ def get_tox_envs(tox_ini_path: Path) -> list: def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: - - os_alias = { - "ubuntu-latest": "Ubuntu", - "windows-latest": "Windows" - } + os_alias = {"ubuntu-latest": "Ubuntu", "windows-latest": "Windows"} python_version_alias = { "pypy3": "pypy-3.8", @@ -67,7 +59,6 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: for operating_system in operating_systems: for tox_env in tox_envs: - tox_test_env_match = _tox_test_env_regex.match(tox_env) if tox_test_env_match is None: @@ -75,9 +66,9 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: groups = tox_test_env_match.groupdict() - aliased_python_version = ( - python_version_alias[groups["python_version"]] - ) + aliased_python_version = python_version_alias[ + groups["python_version"] + ] tox_env = tox_test_env_match.string test_requirements = groups["test_requirements"] @@ -99,20 +90,17 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: ), "python_version": aliased_python_version, "tox_env": tox_env, - "os": operating_system + "os": operating_system, } - ) return test_job_datas def get_lint_job_datas(tox_envs: list) -> list: - lint_job_datas = [] for tox_env in tox_envs: - tox_lint_env_match = _tox_lint_env_regex.match(tox_env) if tox_lint_env_match is None: @@ -126,18 +114,15 @@ def get_lint_job_datas(tox_envs: list) -> list: "ui_name": f"{tox_lint_env_match.groupdict()['name']}", "tox_env": tox_env, } - ) return lint_job_datas def get_contrib_job_datas(tox_envs: list) -> list: - contrib_job_datas = [] for tox_env in tox_envs: - tox_contrib_env_match = _tox_contrib_env_regex.match(tox_env) if tox_contrib_env_match is None: @@ -157,30 +142,25 @@ def get_contrib_job_datas(tox_envs: list) -> list: contrib_job_datas.append( { - "ui_name": ( - f"{groups['name']}" - f"{contrib_requirements}" - ), + "ui_name": (f"{groups['name']}" f"{contrib_requirements}"), "tox_env": tox_env, } - ) return contrib_job_datas def get_misc_job_datas(tox_envs: list) -> list: - misc_job_datas = [] _tox_benchmark_env_regex = re_compile(r"benchmark.+") for tox_env in tox_envs: if ( - _tox_test_env_regex.match(tox_env) is not None or - _tox_lint_env_regex.match(tox_env) is not None or - _tox_contrib_env_regex.match(tox_env) is not None or - _tox_benchmark_env_regex.match(tox_env) is not None + _tox_test_env_regex.match(tox_env) is not None + or _tox_lint_env_regex.match(tox_env) is not None + or _tox_contrib_env_regex.match(tox_env) is not None + or _tox_benchmark_env_regex.match(tox_env) is not None ): continue @@ -192,41 +172,32 @@ def get_misc_job_datas(tox_envs: list) -> list: def _generate_workflow( job_datas: list, name: str, workflow_directory_path: Path ): - # Github seems to limit the amount of jobs in a workflow file, that is why # they are split in groups of 250 per workflow file. for file_number, job_datas in enumerate( [ - job_datas[index:index + 250] + job_datas[index : index + 250] for index in range(0, len(job_datas), 250) ] ): - with open( - workflow_directory_path.joinpath(f"{name}_{file_number}.yml"), - "w" + workflow_directory_path.joinpath(f"{name}_{file_number}.yml"), "w" ) as test_yml_file: - test_yml_file.write( - Environment( - loader=FileSystemLoader(Path(__file__).parent) - ).get_template(f"{name}.yml.j2").render( - job_datas=job_datas, file_number=file_number - ) + Environment(loader=FileSystemLoader(Path(__file__).parent)) + .get_template(f"{name}.yml.j2") + .render(job_datas=job_datas, file_number=file_number) ) test_yml_file.write("\n") def generate_test_workflow( - tox_ini_path: Path, - workflow_directory_path: Path, - *operating_systems + tox_ini_path: Path, workflow_directory_path: Path, *operating_systems ) -> None: - _generate_workflow( get_test_job_datas(get_tox_envs(tox_ini_path), operating_systems), "test", - workflow_directory_path + workflow_directory_path, ) @@ -234,24 +205,22 @@ def generate_lint_workflow( tox_ini_path: Path, workflow_directory_path: Path, ) -> None: - _generate_workflow( get_lint_job_datas(get_tox_envs(tox_ini_path)), "lint", - workflow_directory_path + workflow_directory_path, ) def generate_contrib_workflow( workflow_directory_path: Path, ) -> None: - _generate_workflow( get_contrib_job_datas( get_tox_envs(Path(__file__).parent.joinpath("tox.ini")) ), "contrib", - workflow_directory_path + workflow_directory_path, ) @@ -259,9 +228,8 @@ def generate_misc_workflow( tox_ini_path: Path, workflow_directory_path: Path, ) -> None: - _generate_workflow( get_misc_job_datas(get_tox_envs(tox_ini_path)), "misc", - workflow_directory_path + workflow_directory_path, ) diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index edb96b60d1..e367048b72 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -132,3 +132,21 @@ jobs: - name: Run tests run: tox -e shellcheck + + ruff: + name: ruff + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e ruff diff --git a/.isort.cfg b/.isort.cfg deleted file mode 100644 index afe42d3d41..0000000000 --- a/.isort.cfg +++ /dev/null @@ -1,19 +0,0 @@ -[settings] -include_trailing_comma=True -force_grid_wrap=0 -use_parentheses=True -line_length=79 -profile=black - -; 3 stands for Vertical Hanging Indent, e.g. -; from third_party import ( -; lib1, -; lib2, -; lib3, -; ) -; docs: https://github.com/timothycrosley/isort#multi-line-output-modes -multi_line_output=3 -skip=target -skip_glob=**/gen/*,.venv*/*,venv*/*,.tox/* -known_first_party=opentelemetry -known_third_party=psutil,pytest,redis,redis_opentracing diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b01b7ce4d7..bf0e8f7653 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,10 @@ repos: - - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.3.0 - hooks: - - id: black - language_version: python3.12 - - repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - - repo: https://github.com/pycqa/flake8 - rev: '6.1.0' - hooks: - - id: flake8 +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.6.9 + hooks: + # Run the linter. + - id: ruff + args: ["--fix", "--show-fixes"] + # Run the formatter. + - id: ruff-format diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 61f261f001..8d72683692 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,20 +67,15 @@ You can run `tox` with the following arguments: Python version * `tox -e spellcheck` to run a spellcheck on all the code * `tox -e lint-some-package` to run lint checks on `some-package` +* `tox -e ruff` to run ruff linter and formatter checks against the entire codebase -`black` and `isort` are executed when `tox -e lint` is run. The reported errors can be tedious to fix manually. -An easier way to do so is: - -1. Run `.tox/lint/bin/black .` -2. Run `.tox/lint/bin/isort .` - -Or you can call formatting and linting in one command by [pre-commit](https://pre-commit.com/): +`ruff check` and `ruff format` are executed when `tox -e ruff` is run. We strongly recommend you to configure [pre-commit](https://pre-commit.com/) locally to run `ruff` automatically before each commit by installing it as git hooks. You just need to [install pre-commit](https://pre-commit.com/#install) in your environment: ```console -$ pre-commit +$ pip install pre-commit -c dev-requirements.txt ``` -You can also configure it to run lint tools automatically before committing with: +and run this command inside the git repository: ```console $ pre-commit install diff --git a/_template/pyproject.toml b/_template/pyproject.toml index 514b537f42..b180d32ad8 100644 --- a/_template/pyproject.toml +++ b/_template/pyproject.toml @@ -35,7 +35,7 @@ dependencies = [ [project.entry-points.opentelemetry_instrumentor] # REPLACE ME: the entrypoint for the instrumentor e.g # sqlalchemy = "opentelemetry.instrumentation.sqlalchemy:SQLAlchemyInstrumentor" - = "opentelemetry.instrumentation." +REPLACE_ME = "opentelemetry.instrumentation." [project.urls] # url of the instrumentation e.g diff --git a/dev-requirements.txt b/dev-requirements.txt index 3289650ac8..70464ffdd7 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,4 @@ pylint==3.0.2 -flake8==6.1.0 -isort==5.12.0 -black==24.3.0 httpretty==1.1.4 mypy==0.931 sphinx==7.1.2 @@ -19,3 +16,4 @@ ruamel.yaml==0.17.21 flaky==3.7.0 pre-commit==3.7.0; python_version >= '3.9' pre-commit==3.5.0; python_version < '3.9' +ruff==0.6.9 diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py index 652e5eae8d..78b8516a46 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py @@ -29,14 +29,14 @@ Sample, TimeSeries, ) -from opentelemetry.sdk.metrics import Counter -from opentelemetry.sdk.metrics import Histogram as ClientHistogram from opentelemetry.sdk.metrics import ( + Counter, ObservableCounter, ObservableGauge, ObservableUpDownCounter, UpDownCounter, ) +from opentelemetry.sdk.metrics import Histogram as ClientHistogram from opentelemetry.sdk.metrics.export import ( AggregationTemporality, Gauge, diff --git a/gen-requirements.txt b/gen-requirements.txt index b2d5c4f695..074806f30f 100644 --- a/gen-requirements.txt +++ b/gen-requirements.txt @@ -2,8 +2,7 @@ astor==0.8.1 jinja2==3.1.4 markupsafe==2.0.1 -isort -black +ruff==0.6.9 requests tomli tomli_w diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py index caf0e5b1a9..48a936dc61 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py @@ -40,7 +40,7 @@ async def wrapper(wrapped, instance, args, kwargs): async def consume( callback: Callable[[AbstractIncomingMessage], Any], *fargs, - **fkwargs + **fkwargs, ): decorated_callback = CallbackDecorator( tracer, instance diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/span_builder.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/span_builder.py index c62b1ea9bf..dd5433756c 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/span_builder.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/span_builder.py @@ -69,23 +69,27 @@ def set_channel(self, channel: AbstractChannel): def set_message(self, message: AbstractMessage): properties = message.properties if properties.message_id: - self._attributes[ - SpanAttributes.MESSAGING_MESSAGE_ID - ] = properties.message_id + self._attributes[SpanAttributes.MESSAGING_MESSAGE_ID] = ( + properties.message_id + ) if properties.correlation_id: - self._attributes[ - SpanAttributes.MESSAGING_CONVERSATION_ID - ] = properties.correlation_id + self._attributes[SpanAttributes.MESSAGING_CONVERSATION_ID] = ( + properties.correlation_id + ) def build(self) -> Optional[Span]: if not is_instrumentation_enabled(): return None if self._operation: - self._attributes[SpanAttributes.MESSAGING_OPERATION] = self._operation.value + self._attributes[SpanAttributes.MESSAGING_OPERATION] = ( + self._operation.value + ) else: self._attributes[SpanAttributes.MESSAGING_TEMP_DESTINATION] = True span = self._tracer.start_span( - self._generate_span_name(), kind=self._kind, attributes=self._attributes + self._generate_span_name(), + kind=self._kind, + attributes=self._attributes, ) return span diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 9ebb180de1..33b08fc0b6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -71,7 +71,6 @@ async def do_request(): class TestAioHttpIntegration(TestBase): - _test_status_codes = ( (HTTPStatus.OK, StatusCode.UNSET), (HTTPStatus.TEMPORARY_REDIRECT, StatusCode.UNSET), diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py index e9dfb11389..57eb6234a5 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py @@ -92,7 +92,6 @@ async def fixture_server_fixture(tracer, aiohttp_server, suppress): def test_checking_instrumentor_pkg_installed(): - (instrumentor_entrypoint,) = entry_points( group="opentelemetry_instrumentor", name="aiohttp-server" ) diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py index 7d994be622..507206f4f2 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py @@ -67,6 +67,7 @@ async def async_consume_hook(span, record, args, kwargs): API ___ """ + from asyncio import iscoroutinefunction from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py index a4bde482db..4e6257fbb1 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py @@ -102,7 +102,7 @@ async def traced_execution( cursor, query_method: typing.Callable[..., typing.Any], *args: typing.Tuple[typing.Any, typing.Any], - **kwargs: typing.Dict[typing.Any, typing.Any] + **kwargs: typing.Dict[typing.Any, typing.Any], ): name = "" if args: diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/wrappers.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/wrappers.py index c4252615b8..06098ee7a0 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/wrappers.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/wrappers.py @@ -29,6 +29,7 @@ API --- """ + import logging import typing diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index bc45eacaa4..725532bc15 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -301,9 +301,7 @@ def keys(self, carrier: dict) -> typing.List[str]: class ASGISetter(Setter[dict]): - def set( - self, carrier: dict, key: str, value: str - ) -> None: # pylint: disable=no-self-use + def set(self, carrier: dict, key: str, value: str) -> None: # pylint: disable=no-self-use """Sets response header values on an ASGI scope according to `the spec `_. Args: diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index e83f384a8c..a6cc6b044f 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -76,6 +76,7 @@ def func(): API --- """ + import asyncio import sys from asyncio import futures @@ -163,7 +164,6 @@ def instrument_method_with_coroutine(self, method_name: str): """ def wrap_coro_or_future(method, instance, args, kwargs): - # If the first argument is a coroutine or future, # we decorate it with a span and return the task. if args and len(args) > 0: diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/environment_variables.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/environment_variables.py index 7420ea362f..9f324d60f4 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/environment_variables.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/environment_variables.py @@ -15,6 +15,7 @@ """ Enter the names of the coroutines to be traced through the environment variable below, separated by commas. """ + OTEL_PYTHON_ASYNCIO_COROUTINE_NAMES_TO_TRACE = ( "OTEL_PYTHON_ASYNCIO_COROUTINE_NAMES_TO_TRACE" ) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py index 5241b3f2cc..f964044fc7 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -56,7 +56,7 @@ async def async_gen(): yield it async_gen_instance = async_gen() - agen = anext(async_gen_instance) + agen = anext(async_gen_instance) # noqa: F821 return await asyncio.create_task(agen) ret = asyncio.run(main()) diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py index ba76254aa8..306f8b15c0 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py @@ -96,7 +96,6 @@ def _hydrate_span_from_args(connection, query, parameters) -> dict: class AsyncPGInstrumentor(BaseInstrumentor): - _leading_comment_remover = re.compile(r"^/\*.*?\*/") _tracer = None diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index fb5da8ce48..68db87ca30 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -258,13 +258,11 @@ def _instrument( tracer_provider: TracerProvider = None, meter_provider: MeterProvider = None, ): - # pylint: disable=too-many-locals # pylint: disable=too-many-statements def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches call_wrapped, instance, args, kwargs ): - orig_handler_name = ".".join( [wrapped_module_name, wrapped_function_name] ) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index 7f805c327c..4ac1e9c873 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -70,9 +70,7 @@ def __init__(self, aws_request_id, invoked_function_arn): SpanAttributes.FAAS_INVOCATION_ID: MOCK_LAMBDA_CONTEXT.aws_request_id, ResourceAttributes.CLOUD_ACCOUNT_ID: MOCK_LAMBDA_CONTEXT.invoked_function_arn.split( ":" - )[ - 4 - ], + )[4], } MOCK_XRAY_TRACE_ID = 0x5FB7331105E8BB83207FA31D4D9CDB4C diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py index c0231f81e4..83e5ed70bc 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py @@ -28,6 +28,7 @@ --- """ + import logging from typing import Any, Collection, Dict, Generator, List, Mapping, Optional diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/_messaging.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/_messaging.py index 271a8475e6..fdb1c7f8a5 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/_messaging.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/_messaging.py @@ -35,7 +35,7 @@ def set(self, carrier: CarrierT, key: str, value: str): def inject_propagation_context( - carrier: MutableMapping[str, Any] + carrier: MutableMapping[str, Any], ) -> MutableMapping[str, Any]: if carrier is None: carrier = {} diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index 95a14627b3..aaf906d118 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -97,6 +97,7 @@ def instrument_consumer(consumer: Consumer, tracer_provider=None) ___ """ + from typing import Collection import confluent_kafka @@ -123,9 +124,7 @@ def instrument_consumer(consumer: Consumer, tracer_provider=None) class AutoInstrumentedProducer(Producer): # This method is deliberately implemented in order to allow wrapt to wrap this function - def produce( - self, topic, value=None, *args, **kwargs - ): # pylint: disable=keyword-arg-before-vararg,useless-super-delegation + def produce(self, topic, value=None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg,useless-super-delegation super().produce(topic, value, *args, **kwargs) @@ -139,9 +138,7 @@ def poll(self, timeout=-1): # pylint: disable=useless-super-delegation return super().poll(timeout) # This method is deliberately implemented in order to allow wrapt to wrap this function - def consume( - self, *args, **kwargs - ): # pylint: disable=useless-super-delegation + def consume(self, *args, **kwargs): # pylint: disable=useless-super-delegation return super().consume(*args, **kwargs) # This method is deliberately implemented in order to allow wrapt to wrap this function @@ -163,9 +160,7 @@ def poll(self, timeout=-1): def purge(self, in_queue=True, in_flight=True, blocking=True): self._producer.purge(in_queue, in_flight, blocking) - def produce( - self, topic, value=None, *args, **kwargs - ): # pylint: disable=keyword-arg-before-vararg + def produce(self, topic, value=None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg new_kwargs = kwargs.copy() new_kwargs["topic"] = topic new_kwargs["value"] = value @@ -205,9 +200,7 @@ def consume(self, *args, **kwargs): kwargs, ) - def get_watermark_offsets( - self, partition, timeout=-1, *args, **kwargs - ): # pylint: disable=keyword-arg-before-vararg + def get_watermark_offsets(self, partition, timeout=-1, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg return self._consumer.get_watermark_offsets( partition, timeout, *args, **kwargs ) @@ -220,9 +213,7 @@ def poll(self, timeout=-1): self._consumer.poll, self, self._tracer, [timeout], {} ) - def subscribe( - self, topics, on_assign=lambda *args: None, *args, **kwargs - ): # pylint: disable=keyword-arg-before-vararg + def subscribe(self, topics, on_assign=lambda *args: None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg self._consumer.subscribe(topics, on_assign, *args, **kwargs) def original_consumer(self): diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py index 92e11798f6..f87dbd6576 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/utils.py @@ -8,9 +8,7 @@ def __init__(self, queue, config): self._queue = queue super().__init__(config) - def consume( - self, num_messages=1, *args, **kwargs - ): # pylint: disable=keyword-arg-before-vararg + def consume(self, num_messages=1, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg messages = self._queue[:num_messages] self._queue = self._queue[num_messages:] return messages @@ -62,9 +60,7 @@ def __init__(self, queue, config): self._queue = queue super().__init__(config) - def produce( - self, *args, **kwargs - ): # pylint: disable=keyword-arg-before-vararg + def produce(self, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg self._queue.append( MockedMessage( topic=kwargs.get("topic"), diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 667d6f1091..da807cc310 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -40,7 +40,10 @@ _start_internal_or_server_span, extract_attributes_from_object, ) -from opentelemetry.instrumentation.wsgi import add_response_attributes +from opentelemetry.instrumentation.wsgi import ( + add_response_attributes, + wsgi_getter, +) from opentelemetry.instrumentation.wsgi import ( collect_custom_request_headers_attributes as wsgi_collect_custom_request_headers_attributes, ) @@ -50,7 +53,6 @@ from opentelemetry.instrumentation.wsgi import ( collect_request_attributes as wsgi_collect_request_attributes, ) -from opentelemetry.instrumentation.wsgi import wsgi_getter from opentelemetry.semconv.attributes.http_attributes import HTTP_ROUTE from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import Span, SpanKind, use_span @@ -107,14 +109,17 @@ def __call__(self, request): # try/except block exclusive for optional ASGI imports. try: - from opentelemetry.instrumentation.asgi import asgi_getter, asgi_setter + from opentelemetry.instrumentation.asgi import ( + asgi_getter, + asgi_setter, + set_status_code, + ) from opentelemetry.instrumentation.asgi import ( collect_custom_headers_attributes as asgi_collect_custom_headers_attributes, ) from opentelemetry.instrumentation.asgi import ( collect_request_attributes as asgi_collect_request_attributes, ) - from opentelemetry.instrumentation.asgi import set_status_code _is_asgi_supported = True except ImportError: diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/views.py b/instrumentation/opentelemetry-instrumentation-django/tests/views.py index 6310664100..f2ede18b74 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/views.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/views.py @@ -25,9 +25,7 @@ def excluded_noarg2(request): # pylint: disable=unused-argument return HttpResponse() -def route_span_name( - request, *args, **kwargs -): # pylint: disable=unused-argument +def route_span_name(request, *args, **kwargs): # pylint: disable=unused-argument return HttpResponse() @@ -49,9 +47,7 @@ async def async_traced(request): # pylint: disable=unused-argument return HttpResponse() -async def async_traced_template( - request, year -): # pylint: disable=unused-argument +async def async_traced_template(request, year): # pylint: disable=unused-argument return HttpResponse() @@ -71,9 +67,7 @@ async def async_excluded_noarg2(request): # pylint: disable=unused-argument return HttpResponse() -async def async_route_span_name( - request, *args, **kwargs -): # pylint: disable=unused-argument +async def async_route_span_name(request, *args, **kwargs): # pylint: disable=unused-argument return HttpResponse() diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 2dce5f1ef5..28b394eaf0 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -296,9 +296,7 @@ def __del__(self): if self in _InstrumentedFalconAPI._instrumented_falcon_apps: _InstrumentedFalconAPI._instrumented_falcon_apps.remove(self) - def _handle_exception( - self, arg1, arg2, arg3, arg4 - ): # pylint: disable=C0103 + def _handle_exception(self, arg1, arg2, arg3, arg4): # pylint: disable=C0103 # Falcon 3 does not execute middleware within the context of the exception # so we capture the exception here and save it into the env dict @@ -437,9 +435,7 @@ def process_resource(self, req, resp, resource, params): resource_name = resource.__class__.__name__ span.set_attribute("falcon.resource", resource_name) - def process_response( - self, req, resp, resource, req_succeeded=None - ): # pylint:disable=R0201,R0912 + def process_response(self, req, resp, resource, req_succeeded=None): # pylint:disable=R0201,R0912 span = req.env.get(_ENVIRON_SPAN_KEY) if not span or not span.is_recording(): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index bde91ccfcf..fdbad4effb 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -1073,9 +1073,7 @@ def test_instruments_with_fastapi_installed(self, mock_version): self.assertEqual(ep.name, "fastapi") @patch("opentelemetry.instrumentation.dependencies.version") - def test_instruments_with_old_fastapi_installed( - self, mock_version - ): # pylint: disable=no-self-use + def test_instruments_with_old_fastapi_installed(self, mock_version): # pylint: disable=no-self-use mock_version.side_effect = mock_version_with_old_fastapi mock_distro = Mock() _load_instrumentors(mock_distro) @@ -1083,9 +1081,7 @@ def test_instruments_with_old_fastapi_installed( mock_distro.load_instrumentor.assert_not_called() @patch("opentelemetry.instrumentation.dependencies.version") - def test_instruments_without_fastapi_installed( - self, mock_version - ): # pylint: disable=no-self-use + def test_instruments_without_fastapi_installed(self, mock_version): # pylint: disable=no-self-use mock_version.side_effect = mock_version_without_fastapi mock_distro = Mock() _load_instrumentors(mock_distro) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py index e7adca735c..0a1b20155e 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation_custom_headers.py @@ -18,7 +18,6 @@ class MultiMapping(Mapping): - def __init__(self, *items: Tuple[str, str]): self._items = items 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 761fa3660f..f80c0de808 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -238,6 +238,7 @@ def response_hook(span: Span, status: str, response_headers: List): API --- """ + import weakref from logging import getLogger from time import time_ns diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py index 717977146e..ff0fa93902 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py @@ -273,6 +273,7 @@ async def serve(): services ``GRPCTestServer`` and ``GRPCHealthServer``. """ + import os from typing import Callable, Collection, List, Union diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py index 32cec6dee0..c7eec06c99 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/grpcext/_interceptor.py @@ -17,7 +17,6 @@ """Implementation of gRPC Python interceptors.""" - import collections import grpc diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 15ee59a183..b9b9a31d3e 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -190,6 +190,7 @@ async def async_response_hook(span, request, response): API --- """ + import logging import typing from asyncio import iscoroutinefunction @@ -306,7 +307,7 @@ def _inject_propagation_headers(headers, args, kwargs): def _extract_response( response: typing.Union[ httpx.Response, typing.Tuple[int, Headers, httpx.SyncByteStream, dict] - ] + ], ) -> typing.Tuple[int, Headers, httpx.SyncByteStream, dict, str]: if isinstance(response, httpx.Response): status_code = response.status_code @@ -557,7 +558,9 @@ async def __aexit__( await self._transport.__aexit__(exc_type, exc_value, traceback) # pylint: disable=R0914 - async def handle_async_request(self, *args, **kwargs) -> typing.Union[ + async def handle_async_request( + self, *args, **kwargs + ) -> typing.Union[ typing.Tuple[int, "Headers", httpx.AsyncByteStream, dict], httpx.Response, ]: @@ -849,7 +852,7 @@ def instrument_client( @staticmethod def uninstrument_client( - client: typing.Union[httpx.Client, httpx.AsyncClient] + client: typing.Union[httpx.Client, httpx.AsyncClient], ): """Disables instrumentation for the given client instance diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 27535800cb..0d055515e0 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -911,7 +911,6 @@ def test_instrument_client(self): self.assert_span(num_spans=1) def test_instrumentation_without_client(self): - HTTPXClientInstrumentor().instrument() results = [ httpx.get(self.URL), diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py index b29990d6e3..9b0f4895f9 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py @@ -67,6 +67,7 @@ def consume_hook(span, record, args, kwargs): API ___ """ + from importlib.metadata import PackageNotFoundError, distribution from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py index ce332d0113..35d202215d 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py @@ -36,7 +36,7 @@ get_tracer_provider, ) -__doc__ = _MODULE_DOC +__doc__ = _MODULE_DOC # noqa: A001 LEVELS = { "debug": logging.DEBUG, diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py index b18f93364f..5eb6798231 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py @@ -136,6 +136,4 @@ are not injected into the log record objects. This means any attempted log statements made after setting the logging format and before enabling this integration will result in KeyError exceptions. Such exceptions are automatically swallowed by the logging module and do not result in crashes but you may still lose out on important log messages. -""".format( - default_logging_format=DEFAULT_LOGGING_FORMAT -) +""".format(default_logging_format=DEFAULT_LOGGING_FORMAT) diff --git a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py index c8b8744cf3..4045a44204 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py +++ b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py @@ -146,9 +146,7 @@ def test_custom_format_and_level_env(self, basic_config_mock): env_patch.stop() @mock.patch("logging.basicConfig") - def test_custom_format_and_level_api( - self, basic_config_mock - ): # pylint: disable=no-self-use + def test_custom_format_and_level_api(self, basic_config_mock): # pylint: disable=no-self-use LoggingInstrumentor().uninstrument() LoggingInstrumentor().instrument( set_logging_format=True, diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py index 64f74eaefe..347ddb70ff 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -40,7 +40,6 @@ --- """ - from typing import Collection from wrapt import wrap_function_wrapper @@ -55,7 +54,6 @@ class OpenAIInstrumentor(BaseInstrumentor): - def instrumentation_dependencies(self) -> Collection[str]: return _instruments diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index e139a799cb..ddc54cad19 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -40,7 +40,6 @@ def chat_completions_create(tracer: Tracer): """Wrap the `create` method of the `ChatCompletion` class to trace it.""" def traced_method(wrapped, instance, args, kwargs): - llm_prompts = [] for item in kwargs.get("messages", []): diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 7d0eddc58d..ba2301cc5d 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -142,7 +142,6 @@ def get_llm_request_attributes( kwargs, operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value, ): - attributes = { GenAIAttributes.GEN_AI_OPERATION_NAME: operation_name, GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value, diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py index 4f61713b29..e986ec0d46 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py @@ -185,10 +185,12 @@ def _uninstrument(self, **kwargs): """ "Disable Psycopg instrumentation""" dbapi.unwrap_connect(psycopg, "connect") # pylint: disable=no-member dbapi.unwrap_connect( - psycopg.Connection, "connect" # pylint: disable=no-member + psycopg.Connection, + "connect", # pylint: disable=no-member ) dbapi.unwrap_connect( - psycopg.AsyncConnection, "connect" # pylint: disable=no-member + psycopg.AsyncConnection, + "connect", # pylint: disable=no-member ) # TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py b/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py index 4e29091217..f888009017 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py @@ -52,9 +52,7 @@ ) -class PymemcacheClientTestCase( - TestBase -): # pylint: disable=too-many-public-methods +class PymemcacheClientTestCase(TestBase): # pylint: disable=too-many-public-methods """Tests for a patched pymemcache.client.base.Client.""" def setUp(self): diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py index f55aa2be33..e0721f2f2d 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py @@ -74,6 +74,7 @@ def failed_hook(span, event): collection.find_one() """ + from logging import getLogger from typing import Callable, Collection diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index 7d3c8a334a..6136d55558 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -184,6 +184,7 @@ API --- """ + import platform from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index 1d3b8b8a87..e81beb6f3d 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -90,6 +90,7 @@ def response_hook(span, instance, response): API --- """ + import typing from typing import Any, Collection diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py index 24ca387861..aa26ee7d1c 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py @@ -15,6 +15,7 @@ """ Some utils used by the redis integration """ + from opentelemetry.semconv.trace import ( DbSystemValues, NetTransportValues, diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py index 56e544edcd..9f09168c6f 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py @@ -43,6 +43,7 @@ def multiply(x, y): multiply.send(43, 51) """ + from typing import Collection from remoulade import Middleware, broker diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py index 2107bc3e23..9889e18b5a 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py @@ -94,6 +94,7 @@ API --- """ + from collections.abc import Sequence from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index 474a942a98..50d2fb03d8 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -169,6 +169,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A API --- """ + from typing import Collection from starlette import applications diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py index 0b5e06b526..3a19450433 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -152,7 +152,6 @@ def client_response_hook(span, future): --- """ - from collections import namedtuple from functools import partial from logging import getLogger diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/__init__.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/__init__.py index cebcb81ced..da31287c83 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/__init__.py @@ -39,6 +39,7 @@ API --- """ + from typing import Collection import wrapt diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index d9072ba727..8b72a2f3db 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -197,9 +197,7 @@ def _instrument(self, **kwargs): def _uninstrument(self, **kwargs): _uninstrument() - def uninstrument_opener( - self, opener: OpenerDirector - ): # pylint: disable=no-self-use + def uninstrument_opener(self, opener: OpenerDirector): # pylint: disable=no-self-use """uninstrument_opener a specific instance of urllib.request.OpenerDirector""" _uninstrument_from(opener, restore_as_bound_func=True) @@ -376,7 +374,6 @@ def _set_status_code_attribute( metric_attributes: dict = None, sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ) -> None: - status_code_str = str(status_code) try: status_code = int(status_code) diff --git a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py index 7a9bfd38f1..72fe6ef66f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_metrics_instrumentation.py @@ -404,7 +404,6 @@ def test_basic_metric_request_not_empty(self): ) def test_metric_uninstrument(self): with request.urlopen(self.URL): - self.assertEqual( len( ( @@ -452,7 +451,6 @@ def test_metric_uninstrument(self): ) with request.urlopen(self.URL): - self.assertEqual( len( ( @@ -502,7 +500,6 @@ def test_metric_uninstrument(self): URLLibInstrumentor().uninstrument() with request.urlopen(self.URL): - self.assertEqual( len( ( diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index 1c83f3f447..eda66bea37 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -463,7 +463,6 @@ def _set_status_code_attribute( metric_attributes: dict = None, sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ) -> None: - status_code_str = str(status_code) try: status_code = int(status_code) @@ -490,7 +489,6 @@ def _set_metric_attributes( method: str, sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, ) -> None: - _set_http_host_client( metric_attributes, instance.host, sem_conv_opt_in_mode ) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py index 777d19f41d..095e263732 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py @@ -696,9 +696,9 @@ def test_request_attributes_with_nonstandard_port_and_no_host(self): self.validate_url("http://127.0.0.1:443/", has_host=False) def test_request_attributes_with_conflicting_nonstandard_port(self): - self.environ[ - "HTTP_HOST" - ] += ":8080" # Note that we do not correct SERVER_PORT + self.environ["HTTP_HOST"] += ( + ":8080" # Note that we do not correct SERVER_PORT + ) expected = { SpanAttributes.HTTP_HOST: "127.0.0.1:8080", SpanAttributes.HTTP_URL: "http://127.0.0.1:8080/", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py index 7154238bb7..acc81c701c 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py @@ -137,7 +137,9 @@ def _load_configurators(): configurator_name is None or configurator_name == entry_point.name ): - entry_point.load()().configure(auto_instrumentation_version=__version__) # type: ignore + entry_point.load()().configure( + auto_instrumentation_version=__version__ + ) # type: ignore configured = entry_point.name else: _logger.warning( diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py index 1bc847f988..1b450f2549 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py @@ -32,7 +32,6 @@ class BaseDistro(ABC): _instance = None def __new__(cls, *args, **kwargs): - if cls._instance is None: cls._instance = object.__new__(cls, *args, **kwargs) diff --git a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py index 98bad3d9f9..2d8538b5b3 100644 --- a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py +++ b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py @@ -33,9 +33,7 @@ class TestLoad(TestCase): @patch( "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) - def test_load_configurators( - self, iter_mock - ): # pylint: disable=no-self-use + def test_load_configurators(self, iter_mock): # pylint: disable=no-self-use # Add multiple entry points but only specify the 2nd in the environment variable. ep_mock1 = Mock() ep_mock1.name = "custom_configurator1" @@ -64,9 +62,7 @@ def test_load_configurators( @patch( "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) - def test_load_configurators_no_ep( - self, iter_mock - ): # pylint: disable=no-self-use + def test_load_configurators_no_ep(self, iter_mock): # pylint: disable=no-self-use iter_mock.return_value = () # Confirm method does not crash if not entry points exist. _load._load_configurators() @@ -288,9 +284,7 @@ def test_load_instrumentors(self, iter_mock, dep_mock): @patch( "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" ) - def test_load_instrumentors_dep_conflict( - self, iter_mock, dep_mock - ): # pylint: disable=no-self-use + def test_load_instrumentors_dep_conflict(self, iter_mock, dep_mock): # pylint: disable=no-self-use ep_mock1 = Mock() ep_mock1.name = "instr1" diff --git a/opentelemetry-instrumentation/tests/auto_instrumentation/test_run.py b/opentelemetry-instrumentation/tests/auto_instrumentation/test_run.py index 9fd3a21711..ec01e4089b 100644 --- a/opentelemetry-instrumentation/tests/auto_instrumentation/test_run.py +++ b/opentelemetry-instrumentation/tests/auto_instrumentation/test_run.py @@ -93,9 +93,7 @@ class TestExecl(TestCase): @patch("sys.argv", ["1", "2", "3"]) @patch("opentelemetry.instrumentation.auto_instrumentation.which") @patch("opentelemetry.instrumentation.auto_instrumentation.execl") - def test_execl( - self, mock_execl, mock_which - ): # pylint: disable=no-self-use + def test_execl(self, mock_execl, mock_which): # pylint: disable=no-self-use mock_which.configure_mock(**{"return_value": "python"}) auto_instrumentation.run() diff --git a/opentelemetry-instrumentation/tests/test_distro.py b/opentelemetry-instrumentation/tests/test_distro.py index 03a95614df..9801264cbe 100644 --- a/opentelemetry-instrumentation/tests/test_distro.py +++ b/opentelemetry-instrumentation/tests/test_distro.py @@ -32,9 +32,7 @@ def _uninstrument(self, **kwargs): class MockEntryPoint(EntryPoint): - def __init__( - self, name, value, group - ): # pylint: disable=super-init-not-called + def __init__(self, name, value, group): # pylint: disable=super-init-not-called pass def load(self, *args, **kwargs): # pylint: disable=signature-differs diff --git a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py index 295a5def9b..d9b99f35ca 100644 --- a/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py +++ b/propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py @@ -340,7 +340,6 @@ def extract( context: typing.Optional[Context] = None, getter: Getter[CarrierT] = default_getter, ) -> Context: - xray_context = super().extract(carrier, context=context, getter=getter) if trace.get_current_span(context=context).get_span_context().is_valid: diff --git a/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py b/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py index 2d8937e1b3..231b5da55e 100644 --- a/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py +++ b/propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_lambda_propagator.py @@ -37,9 +37,7 @@ class AwsXRayLambdaPropagatorTest(TestCase): - def test_extract_no_environment_variable(self): - actual_context = get_current_span( AwsXRayLambdaPropagator().extract( {}, context=get_current(), getter=DefaultGetter() @@ -54,9 +52,7 @@ def test_extract_no_environment_variable(self): self.assertEqual(actual_context.trace_state, TraceState.get_default()) def test_extract_no_environment_variable_valid_context(self): - with use_span(NonRecordingSpan(SpanContext(1, 2, False))): - actual_context = get_current_span( AwsXRayLambdaPropagator().extract( {}, context=get_current(), getter=DefaultGetter() @@ -82,7 +78,6 @@ def test_extract_no_environment_variable_valid_context(self): }, ) def test_extract_from_environment_variable(self): - actual_context = get_current_span( AwsXRayLambdaPropagator().extract( {}, context=get_current(), getter=DefaultGetter() @@ -108,7 +103,6 @@ def test_extract_from_environment_variable(self): }, ) def test_add_link_from_environment_variable(self): - propagator = AwsXRayLambdaPropagator() default_getter = DefaultGetter() diff --git a/pyproject.toml b/pyproject.toml index c1a64c5240..fd5ee5716f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,41 @@ -[tool.black] +[tool.ruff] +# https://docs.astral.sh/ruff/configuration/ +target-version = "py38" line-length = 79 -exclude = ''' -( - \.git - | \.tox - | venv - | build - | dist -) -''' +extend-exclude = [ + "_template", + "*_pb2*.py*", +] +output-format = "concise" + +[tool.ruff.lint] +# https://docs.astral.sh/ruff/linter/#rule-selection +# pylint: https://github.com/astral-sh/ruff/issues/970 +select = [ + "I", # isort + "F", # pyflakes + "E", # pycodestyle errors + "W", # pycodestyle warnings + "PLC", # pylint convention + "PLE", # pylint error + "Q", # flake8-quotes + "A", # flake8-builtins +] +ignore = [ + "E501", # line-too-long +] + +[tool.ruff.lint.per-file-ignores] +"docs/**/*.*" = ["A001"] + +[tool.ruff.lint.isort] +detect-same-package = false # to not consider instrumentation packages as first-party +known-first-party = ["opentelemetry"] +known-third-party = [ + "psutil", + "pytest", + "redis", + "redis_opentracing", + "opencensus", +] + diff --git a/scripts/eachdist.py b/scripts/eachdist.py index 57d98206b7..b82d16a8ec 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -238,7 +238,8 @@ def setup_instparser(instparser): ) fmtparser = subparsers.add_parser( - "format", help="Formats all source code with black and isort.", + "format", + help="Formats all source code with black and isort.", ) fmtparser.set_defaults(func=format_args) fmtparser.add_argument( @@ -248,7 +249,8 @@ def setup_instparser(instparser): ) versionparser = subparsers.add_parser( - "version", help="Get the version for a release", + "version", + help="Get the version for a release", ) versionparser.set_defaults(func=version_args) versionparser.add_argument( @@ -268,7 +270,8 @@ def setup_instparser(instparser): ) findparser = subparsers.add_parser( - "find-package", help="Find package path.", + "find-package", + help="Find package path.", ) findparser.set_defaults(func=find_package_args) findparser.add_argument( @@ -294,10 +297,7 @@ def find_targets_unordered(rootpath): continue if subdir.name.startswith(".") or subdir.name.startswith("venv"): continue - if any( - (subdir / marker).exists() - for marker in ("pyproject.toml",) - ): + if any((subdir / marker).exists() for marker in ("pyproject.toml",)): yield subdir else: yield from find_targets_unordered(subdir) @@ -520,23 +520,16 @@ def parse_subargs(parentargs, args): def lint_args(args): - rootdir = str(find_projectroot()) - runsubprocess( args.dry_run, - ("black", "--config", f"{rootdir}/pyproject.toml", ".") - + (("--diff", "--check") if args.check_only else ()), - cwd=rootdir, + ("ruff", "check") + (() if args.check_only else ("--fix",)), check=True, ) runsubprocess( args.dry_run, - ("isort", "--settings-path", f"{rootdir}/.isort.cfg", ".") - + (("--diff", "--check-only") if args.check_only else ()), - cwd=rootdir, + ("ruff", "format") + (("--check",) if args.check_only else ()), check=True, ) - runsubprocess(args.dry_run, ("flake8", "--config", f"{rootdir}/.flake8", rootdir), check=True) execute_args( parse_subargs( args, ("exec", "pylint {}", "--all", "--mode", "lintroots") @@ -545,7 +538,11 @@ def lint_args(args): execute_args( parse_subargs( args, - ("exec", "python scripts/check_for_valid_readme.py {}", "--all",), + ( + "exec", + "python scripts/check_for_valid_readme.py {}", + "--all", + ), ) ) @@ -585,9 +582,7 @@ def update_changelogs(version): ## [{version}](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v{version}) - {today} -""".format( - version=version, today=today - ) +""".format(version=version, today=today) errors = False try: update_changelog("./CHANGELOG.md", version, new_entry) @@ -634,7 +629,10 @@ def update_version_files(targets, version, packages): print("updating version.py files") targets = filter_packages(targets, packages) update_files( - targets, "version.py", "__version__ .*", f'__version__ = "{version}"', + targets, + "version.py", + "__version__ .*", + f'__version__ = "{version}"', ) @@ -652,7 +650,7 @@ def update_dependencies(targets, version, packages): update_files( targets, "pyproject.toml", - fr"({package_name}.*)==(.*)", + rf"({package_name}.*)==(.*)", r"\1== " + version + '",', ) @@ -690,14 +688,18 @@ def release_args(args): updated_versions = [] excluded = cfg["exclude_release"]["packages"].split() - targets = [target for target in targets if basename(target) not in excluded] + targets = [ + target for target in targets if basename(target) not in excluded + ] for group in versions.split(","): mcfg = cfg[group] version = mcfg["version"] updated_versions.append(version) packages = None if "packages" in mcfg: - packages = [pkg for pkg in mcfg["packages"].split() if pkg not in excluded] + packages = [ + pkg for pkg in mcfg["packages"].split() if pkg not in excluded + ] print(f"update {group} packages to {version}") update_dependencies(targets, version, packages) update_version_files(targets, version, packages) @@ -724,16 +726,15 @@ def format_args(args): format_dir = str(find_projectroot()) if args.path: format_dir = os.path.join(format_dir, args.path) - root_dir = str(find_projectroot()) runsubprocess( args.dry_run, - ("black", "--config", f"{root_dir}/pyproject.toml", "."), + ("ruff", "check", "--fix"), cwd=format_dir, check=True, ) runsubprocess( args.dry_run, - ("isort", "--settings-path", f"{root_dir}/.isort.cfg", "--profile", "black", "."), + ("ruff", "format"), cwd=format_dir, check=True, ) @@ -763,6 +764,7 @@ def version_args(args): print("package not found") sys.exit(1) + def find_package_args(args): root = find_projectroot() for package in find_targets_unordered(root): @@ -774,6 +776,7 @@ def find_package_args(args): print("package not found") sys.exit(1) + def main(): args = parse_args() args.func(args) diff --git a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py index d02febca10..bfb3aa1f48 100644 --- a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py +++ b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py @@ -17,15 +17,13 @@ import redis import redis.asyncio - -from redis.exceptions import ResponseError -from redis.commands.search.indexDefinition import IndexDefinition, IndexType -from redis.commands.search.aggregation import AggregateRequest -from redis.commands.search.query import Query from redis.commands.search.field import ( TextField, VectorField, ) +from redis.commands.search.indexDefinition import IndexDefinition, IndexType +from redis.commands.search.query import Query +from redis.exceptions import ResponseError from opentelemetry import trace from opentelemetry.instrumentation.redis import RedisInstrumentor @@ -644,39 +642,49 @@ def prepare_data(self): self.redis_client.ft("idx:test_vss").dropindex(True) except ResponseError: print("No such index") - item = {"name": "test", - "value": "test_value", - "embeddings": [0.1] * 256} + item = { + "name": "test", + "value": "test_value", + "embeddings": [0.1] * 256, + } pipeline = self.redis_client.pipeline() - pipeline.json().set(f"test:001", "$", item) + pipeline.json().set("test:001", "$", item) res = pipeline.execute() assert False not in res def create_index(self): - schema = ( - TextField("$.name", no_stem=True, as_name="name"), - TextField("$.value", no_stem=True, as_name="value"), - VectorField("$.embeddings", - "FLAT", - { - "TYPE": "FLOAT32", - "DIM": self.embedding_dim, - "DISTANCE_METRIC": "COSINE", - }, - as_name="vector",), - ) - definition = IndexDefinition(prefix=["test:"], index_type=IndexType.JSON) - res = self.redis_client.ft("idx:test_vss").create_index(fields=schema, definition=definition) + schema = ( + TextField("$.name", no_stem=True, as_name="name"), + TextField("$.value", no_stem=True, as_name="value"), + VectorField( + "$.embeddings", + "FLAT", + { + "TYPE": "FLOAT32", + "DIM": self.embedding_dim, + "DISTANCE_METRIC": "COSINE", + }, + as_name="vector", + ), + ) + definition = IndexDefinition( + prefix=["test:"], index_type=IndexType.JSON + ) + res = self.redis_client.ft("idx:test_vss").create_index( + fields=schema, definition=definition + ) assert "OK" in str(res) def test_redis_create_index(self): spans = self.memory_exporter.get_finished_spans() - span = next(span for span in spans if span.name == "redis.create_index") + span = next( + span for span in spans if span.name == "redis.create_index" + ) assert "redis.create_index.fields" in span.attributes def test_redis_query(self): query = "@name:test" - res = self.redis_client.ft("idx:test_vss").search(Query(query)) + self.redis_client.ft("idx:test_vss").search(Query(query)) spans = self.memory_exporter.get_finished_spans() span = next(span for span in spans if span.name == "redis.search") diff --git a/tox.ini b/tox.ini index c6bb6a17a4..62c205513e 100644 --- a/tox.ini +++ b/tox.ini @@ -384,6 +384,7 @@ envlist = generate generate-workflows shellcheck + ruff [testenv] deps = @@ -820,362 +821,185 @@ commands_pre = commands = test-distro: pytest {toxinidir}/opentelemetry-distro/tests {posargs} - lint-distro: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-distro - lint-distro: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-distro - lint-distro: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-distro lint-distro: pylint {toxinidir}/opentelemetry-distro test-opentelemetry-instrumentation: pytest {toxinidir}/opentelemetry-instrumentation/tests {posargs} - lint-opentelemetry-instrumentation: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/opentelemetry-instrumentation - lint-opentelemetry-instrumentation: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/opentelemetry-instrumentation - lint-opentelemetry-instrumentation: flake8 --config {toxinidir}/.flake8 {toxinidir}/opentelemetry-instrumentation lint-opentelemetry-instrumentation: pylint {toxinidir}/opentelemetry-instrumentation test-instrumentation-aiohttp-client: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests {posargs} - lint-instrumentation-aiohttp-client: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client - lint-instrumentation-aiohttp-client: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client - lint-instrumentation-aiohttp-client: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiohttp-client" test-instrumentation-aiohttp-server: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/tests {posargs} - lint-instrumentation-aiohttp-server: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server - lint-instrumentation-aiohttp-server: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server - lint-instrumentation-aiohttp-server: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiohttp-server" test-instrumentation-aiopg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/tests {posargs} - lint-instrumentation-aiopg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg - lint-instrumentation-aiopg: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg - lint-instrumentation-aiopg: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg lint-instrumentation-aiopg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiopg" test-instrumentation-asgi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/tests {posargs} - lint-instrumentation-asgi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi - lint-instrumentation-asgi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi - lint-instrumentation-asgi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi lint-instrumentation-asgi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asgi" test-instrumentation-asyncpg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/tests {posargs} - lint-instrumentation-asyncpg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg - lint-instrumentation-asyncpg: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg - lint-instrumentation-asyncpg: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg lint-instrumentation-asyncpg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asyncpg" test-instrumentation-aws-lambda: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/tests {posargs} - lint-instrumentation-aws-lambda: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda - lint-instrumentation-aws-lambda: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda - lint-instrumentation-aws-lambda: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda lint-instrumentation-aws-lambda: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aws-lambda" test-instrumentation-boto: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/tests {posargs} - lint-instrumentation-boto: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-boto - lint-instrumentation-boto: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-boto - lint-instrumentation-boto: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-boto lint-instrumentation-boto: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-boto" test-instrumentation-botocore: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/tests {posargs} - lint-instrumentation-botocore: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore - lint-instrumentation-botocore: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore - lint-instrumentation-botocore: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore lint-instrumentation-botocore: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-botocore" test-instrumentation-boto3sqs: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/tests {posargs} - lint-instrumentation-boto3sqs: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs - lint-instrumentation-boto3sqs: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs - lint-instrumentation-boto3sqs: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs lint-instrumentation-boto3sqs: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-boto3sqs" test-instrumentation-cassandra: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/tests {posargs} - lint-instrumentation-cassandra: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra - lint-instrumentation-cassandra: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra - lint-instrumentation-cassandra: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra lint-instrumentation-cassandra: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-cassandra" test-instrumentation-celery: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/tests {posargs} - lint-instrumentation-celery: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-celery - lint-instrumentation-celery: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-celery - lint-instrumentation-celery: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-celery lint-instrumentation-celery: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-celery" test-instrumentation-dbapi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/tests {posargs} - lint-instrumentation-dbapi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi - lint-instrumentation-dbapi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi - lint-instrumentation-dbapi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi lint-instrumentation-dbapi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-dbapi" test-instrumentation-django: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-django/tests {posargs} - lint-instrumentation-django: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-django - lint-instrumentation-django: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-django - lint-instrumentation-django: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-django lint-instrumentation-django: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-django" test-instrumentation-elasticsearch: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/tests {posargs} - lint-instrumentation-elasticsearch: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch - lint-instrumentation-elasticsearch: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch - lint-instrumentation-elasticsearch: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch lint-instrumentation-elasticsearch: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-elasticsearch" test-instrumentation-falcon: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/tests {posargs} - lint-instrumentation-falcon: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon - lint-instrumentation-falcon: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon - lint-instrumentation-falcon: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon lint-instrumentation-falcon: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-falcon" test-instrumentation-fastapi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/tests {posargs} - lint-instrumentation-fastapi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi - lint-instrumentation-fastapi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi - lint-instrumentation-fastapi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi lint-instrumentation-fastapi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-fastapi" test-instrumentation-flask: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/tests {posargs} - lint-instrumentation-flask: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-flask - lint-instrumentation-flask: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-flask - lint-instrumentation-flask: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-flask lint-instrumentation-flask: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-flask" test-instrumentation-urllib: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib/tests {posargs} - lint-instrumentation-urllib: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib - lint-instrumentation-urllib: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib - lint-instrumentation-urllib: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib lint-instrumentation-urllib: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-urllib" test-instrumentation-urllib3: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/tests {posargs} - lint-instrumentation-urllib3: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3 - lint-instrumentation-urllib3: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3 - lint-instrumentation-urllib3: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3 lint-instrumentation-urllib3: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-urllib3" test-instrumentation-grpc: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/tests {posargs} - lint-instrumentation-grpc: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc - lint-instrumentation-grpc: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc - lint-instrumentation-grpc: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc lint-instrumentation-grpc: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-grpc" test-instrumentation-jinja2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2/tests {posargs} - lint-instrumentation-jinja2: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 - lint-instrumentation-jinja2: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 - lint-instrumentation-jinja2: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2 lint-instrumentation-jinja2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-jinja2" test-instrumentation-aiokafka: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka/tests {posargs} - lint-instrumentation-aiokafka: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka - lint-instrumentation-aiokafka: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka - lint-instrumentation-aiokafka: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka lint-instrumentation-aiokafka: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aiokafka" test-instrumentation-kafka-python: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/tests {posargs} - lint-instrumentation-kafka-python: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python - lint-instrumentation-kafka-python: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python - lint-instrumentation-kafka-python: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python lint-instrumentation-kafka-python: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-kafka-python" ; Test only for kafka-pythonng instrumentation as the only difference between kafka-python and kafka-pythonng is the version of kafka-python test-instrumentation-kafka-pythonng: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/tests {posargs} test-instrumentation-confluent-kafka: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests {posargs} - lint-instrumentation-confluent-kafka: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka - lint-instrumentation-confluent-kafka: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka - lint-instrumentation-confluent-kafka: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-confluent-kafka" test-instrumentation-logging: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/tests {posargs} - lint-instrumentation-logging: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-logging - lint-instrumentation-logging: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-logging - lint-instrumentation-logging: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-logging lint-instrumentation-logging: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-logging" test-instrumentation-mysql: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/tests {posargs} - lint-instrumentation-mysql: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql - lint-instrumentation-mysql: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql - lint-instrumentation-mysql: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql lint-instrumentation-mysql: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysql" test-instrumentation-mysqlclient: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/tests {posargs} - lint-instrumentation-mysqlclient: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient - lint-instrumentation-mysqlclient: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient - lint-instrumentation-mysqlclient: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient lint-instrumentation-mysqlclient: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysqlclient" test-instrumentation-sio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests {posargs} - lint-instrumentation-sio-pika: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pika - lint-instrumentation-sio-pika: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pika - lint-instrumentation-sio-pika: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pika lint-instrumentation-sio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pika" test-instrumentation-aio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/tests {posargs} - lint-instrumentation-aio-pika: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika - lint-instrumentation-aio-pika: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika - lint-instrumentation-aio-pika: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika lint-instrumentation-aio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aio-pika" test-instrumentation-psycopg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/tests {posargs} - lint-instrumentation-psycopg: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg - lint-instrumentation-psycopg: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg - lint-instrumentation-psycopg: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg lint-instrumentation-psycopg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-psycopg" test-instrumentation-psycopg2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/tests {posargs} - lint-instrumentation-psycopg2: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 - lint-instrumentation-psycopg2: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 - lint-instrumentation-psycopg2: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 lint-instrumentation-psycopg2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-psycopg2" test-instrumentation-pymemcache: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/tests {posargs} - lint-instrumentation-pymemcache: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache - lint-instrumentation-pymemcache: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache - lint-instrumentation-pymemcache: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache lint-instrumentation-pymemcache: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymemcache" test-instrumentation-pymongo: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/tests {posargs} - lint-instrumentation-pymongo: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo - lint-instrumentation-pymongo: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo - lint-instrumentation-pymongo: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo lint-instrumentation-pymongo: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymongo" test-instrumentation-pymysql: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/tests {posargs} - lint-instrumentation-pymysql: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql - lint-instrumentation-pymysql: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql - lint-instrumentation-pymysql: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql lint-instrumentation-pymysql: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymysql" test-instrumentation-pyramid: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid/tests {posargs} - lint-instrumentation-pyramid: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid - lint-instrumentation-pyramid: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid - lint-instrumentation-pyramid: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid lint-instrumentation-pyramid: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pyramid" test-instrumentation-redis: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-redis/tests {posargs} - lint-instrumentation-redis: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-redis - lint-instrumentation-redis: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-redis - lint-instrumentation-redis: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-redis lint-instrumentation-redis: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-redis" test-instrumentation-remoulade: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade/tests {posargs} - lint-instrumentation-remoulade: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade - lint-instrumentation-remoulade: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade - lint-instrumentation-remoulade: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade lint-instrumentation-remoulade: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-remoulade" test-instrumentation-requests: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-requests/tests {posargs} - lint-instrumentation-requests: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-requests - lint-instrumentation-requests: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-requests - lint-instrumentation-requests: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-requests lint-instrumentation-requests: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-requests" test-instrumentation-sqlalchemy: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests {posargs} - lint-instrumentation-sqlalchemy: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy - lint-instrumentation-sqlalchemy: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy - lint-instrumentation-sqlalchemy: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy lint-instrumentation-sqlalchemy: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-sqlalchemy" test-instrumentation-sqlite3: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3/tests {posargs} - lint-instrumentation-sqlite3: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3 - lint-instrumentation-sqlite3: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3 - lint-instrumentation-sqlite3: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3 lint-instrumentation-sqlite3: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-sqlite3" test-instrumentation-starlette: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette/tests {posargs} - lint-instrumentation-starlette: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette - lint-instrumentation-starlette: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette - lint-instrumentation-starlette: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette lint-instrumentation-starlette: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-starlette" test-instrumentation-system-metrics: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics/tests {posargs} - lint-instrumentation-system-metrics: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics - lint-instrumentation-system-metrics: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics - lint-instrumentation-system-metrics: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics lint-instrumentation-system-metrics: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-system-metrics" test-instrumentation-threading: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-threading/tests {posargs} - lint-instrumentation-threading: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-threading - lint-instrumentation-threading: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-threading - lint-instrumentation-threading: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-threading lint-instrumentation-threading: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-threading" test-instrumentation-tornado: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado/tests {posargs} - lint-instrumentation-tornado: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado - lint-instrumentation-tornado: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado - lint-instrumentation-tornado: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado lint-instrumentation-tornado: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-tornado" test-instrumentation-tortoiseorm: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm/tests {posargs} - lint-instrumentation-tortoiseorm: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm - lint-instrumentation-tortoiseorm: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm - lint-instrumentation-tortoiseorm: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-tortoiseorm" test-instrumentation-wsgi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/tests {posargs} - lint-instrumentation-wsgi: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi - lint-instrumentation-wsgi: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi - lint-instrumentation-wsgi: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi lint-instrumentation-wsgi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-wsgi" test-instrumentation-httpx: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/tests {posargs} - lint-instrumentation-httpx: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx - lint-instrumentation-httpx: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx - lint-instrumentation-httpx: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx lint-instrumentation-httpx: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-httpx" test-instrumentation-asyncio: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/tests {posargs} - lint-instrumentation-asyncio: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio - lint-instrumentation-asyncio: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio - lint-instrumentation-asyncio: flake8 --config {toxinidir}/.flake8 {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio lint-instrumentation-asyncio: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asyncio" test-util-http: pytest {toxinidir}/util/opentelemetry-util-http/tests {posargs} - lint-util-http: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/util/opentelemetry-util-http - lint-util-http: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/util/opentelemetry-util-http - lint-util-http: flake8 --config {toxinidir}/.flake8 {toxinidir}/util/opentelemetry-util-http lint-util-http: sh -c "cd util && pylint --rcfile ../.pylintrc opentelemetry-util-http" test-sdk-extension-aws: pytest {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/tests {posargs} - lint-sdk-extension-aws: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws - lint-sdk-extension-aws: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws - lint-sdk-extension-aws: flake8 --config {toxinidir}/.flake8 {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws lint-sdk-extension-aws: sh -c "cd sdk-extension && pylint --rcfile ../.pylintrc opentelemetry-sdk-extension-aws" benchmark-sdk-extension-aws: pytest {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/benchmarks {posargs} --benchmark-json=sdk-extension-aws-benchmark.json test-resource-detector-container: pytest {toxinidir}/resource/opentelemetry-resource-detector-container/tests {posargs} - lint-resource-detector-container: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/resource/opentelemetry-resource-detector-container - lint-resource-detector-container: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/resource/opentelemetry-resource-detector-container - lint-resource-detector-container: flake8 --config {toxinidir}/.flake8 {toxinidir}/resource/opentelemetry-resource-detector-container lint-resource-detector-container: sh -c "cd resource && pylint --rcfile ../.pylintrc opentelemetry-resource-detector-container" test-resource-detector-azure: pytest {toxinidir}/resource/opentelemetry-resource-detector-azure/tests {posargs} - lint-resource-detector-azure: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/resource/opentelemetry-resource-detector-azure - lint-resource-detector-azure: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/resource/opentelemetry-resource-detector-azure - lint-resource-detector-azure: flake8 --config {toxinidir}/.flake8 {toxinidir}/resource/opentelemetry-resource-detector-azure lint-resource-detector-azure: sh -c "cd resource && pylint --rcfile ../.pylintrc opentelemetry-resource-detector-azure" test-processor-baggage: pytest {toxinidir}/processor/opentelemetry-processor-baggage/tests {posargs} - lint-processor-baggage: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/processor/opentelemetry-processor-baggage - lint-processor-baggage: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/processor/opentelemetry-processor-baggage - lint-processor-baggage: flake8 --config {toxinidir}/.flake8 {toxinidir}/processor/opentelemetry-processor-baggage lint-processor-baggage: sh -c "cd processor && pylint --rcfile ../.pylintrc opentelemetry-processor-baggage" test-propagator-aws-xray: pytest {toxinidir}/propagator/opentelemetry-propagator-aws-xray/tests {posargs} - lint-propagator-aws-xray: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-aws-xray - lint-propagator-aws-xray: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-aws-xray - lint-propagator-aws-xray: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-aws-xray lint-propagator-aws-xray: sh -c "cd propagator && pylint --rcfile ../.pylintrc opentelemetry-propagator-aws-xray" benchmark-propagator-aws-xray: pytest {toxinidir}/propagator/opentelemetry-propagator-aws-xray/benchmarks {posargs} --benchmark-json=propagator-aws-xray-benchmark.json test-propagator-ot-trace: pytest {toxinidir}/propagator/opentelemetry-propagator-ot-trace/tests {posargs} - lint-propagator-ot-trace: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/propagator/opentelemetry-propagator-ot-trace - lint-propagator-ot-trace: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/propagator/opentelemetry-propagator-ot-trace - lint-propagator-ot-trace: flake8 --config {toxinidir}/.flake8 {toxinidir}/propagator/opentelemetry-propagator-ot-trace lint-propagator-ot-trace: sh -c "cd propagator && pylint --rcfile ../.pylintrc opentelemetry-propagator-ot-trace" test-exporter-richconsole: pytest {toxinidir}/exporter/opentelemetry-exporter-richconsole/tests {posargs} - lint-exporter-richconsole: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-richconsole - lint-exporter-richconsole: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-richconsole - lint-exporter-richconsole: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-richconsole lint-exporter-richconsole: sh -c "cd exporter && pylint --rcfile ../.pylintrc opentelemetry-exporter-richconsole" test-exporter-prometheus-remote-write: pytest {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/tests {posargs} - lint-exporter-prometheus-remote-write: black --diff --check --config {toxinidir}/pyproject.toml {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write - lint-exporter-prometheus-remote-write: isort --diff --check-only --settings-path {toxinidir}/.isort.cfg {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write - lint-exporter-prometheus-remote-write: flake8 --config {toxinidir}/.flake8 {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write: sh -c "cd exporter && pylint --rcfile ../.pylintrc opentelemetry-exporter-prometheus-remote-write" coverage: {toxinidir}/scripts/coverage.sh @@ -1198,17 +1022,6 @@ changedir = docs commands = sphinx-build -E -a -W -b html -T . _build/html -[testenv:lint] -basepython: python3 -recreate = True -deps = - -r dev-requirements.txt - -commands = - black --config {toxinidir}/pyproject.toml {toxinidir} --diff --check - isort --settings-path {toxinidir}/.isort.cfg {toxinidir} --diff --check-only - flake8 --config {toxinidir}/.flake8 {toxinidir} - [testenv:spellcheck] basepython: python3 recreate = True @@ -1364,3 +1177,11 @@ commands_pre = commands = sh -c "find {toxinidir} -name \*.sh | xargs shellcheck --severity=warning" + +[testenv:ruff] +basepython: python3 +deps = + -c {toxinidir}/dev-requirements.txt + pre-commit +commands = + pre-commit run --color=always --all-files {posargs} From 5c566a0c37b8f2b7d483061e878a08f8e81485ce Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 24 Oct 2024 18:34:54 +0200 Subject: [PATCH 200/335] opentelemetry-instrumentation: make it easier to use bootstrap with custom values (#2918) --- .../instrumentation/bootstrap.py | 38 +++++++++----- .../tests/test_bootstrap.py | 49 +++++++++++++++---- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index 02926ea5c4..cc0ac68f1c 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -22,12 +22,15 @@ SubprocessError, check_call, ) +from typing import Optional from packaging.requirements import Requirement from opentelemetry.instrumentation.bootstrap_gen import ( - default_instrumentations, - libraries, + default_instrumentations as gen_default_instrumentations, +) +from opentelemetry.instrumentation.bootstrap_gen import ( + libraries as gen_libraries, ) from opentelemetry.instrumentation.version import __version__ from opentelemetry.util._importlib_metadata import ( @@ -75,7 +78,7 @@ def _sys_pip_install(package): print(error) -def _pip_check(): +def _pip_check(libraries): """Ensures none of the instrumentations have dependency conflicts. Clean check reported as: 'No broken requirements found.' @@ -113,7 +116,7 @@ def _is_installed(req): return True -def _find_installed_libraries(): +def _find_installed_libraries(default_instrumentations, libraries): for lib in default_instrumentations: yield lib @@ -122,18 +125,25 @@ def _find_installed_libraries(): yield lib["instrumentation"] -def _run_requirements(): +def _run_requirements(default_instrumentations, libraries): logger.setLevel(logging.ERROR) - print("\n".join(_find_installed_libraries())) + print( + "\n".join( + _find_installed_libraries(default_instrumentations, libraries) + ) + ) -def _run_install(): - for lib in _find_installed_libraries(): +def _run_install(default_instrumentations, libraries): + for lib in _find_installed_libraries(default_instrumentations, libraries): _sys_pip_install(lib) - _pip_check() + _pip_check(libraries) -def run() -> None: +def run( + default_instrumentations: Optional[list] = None, + libraries: Optional[list] = None, +) -> None: action_install = "install" action_requirements = "requirements" @@ -163,8 +173,14 @@ def run() -> None: ) args = parser.parse_args() + if libraries is None: + libraries = gen_libraries + + if default_instrumentations is None: + default_instrumentations = gen_default_instrumentations + cmd = { action_install: _run_install, action_requirements: _run_requirements, }[args.action] - cmd() + cmd(default_instrumentations, libraries) diff --git a/opentelemetry-instrumentation/tests/test_bootstrap.py b/opentelemetry-instrumentation/tests/test_bootstrap.py index 4807f0beb7..0ded8d37b1 100644 --- a/opentelemetry-instrumentation/tests/test_bootstrap.py +++ b/opentelemetry-instrumentation/tests/test_bootstrap.py @@ -19,7 +19,10 @@ from unittest.mock import call, patch from opentelemetry.instrumentation import bootstrap -from opentelemetry.instrumentation.bootstrap_gen import libraries +from opentelemetry.instrumentation.bootstrap_gen import ( + default_instrumentations, + libraries, +) def sample_packages(packages, rate): @@ -56,15 +59,15 @@ def setUpClass(cls): "opentelemetry.instrumentation.bootstrap._pip_check", ) - cls.pkg_patcher.start() - cls.mock_pip_install = cls.pip_install_patcher.start() - cls.mock_pip_check = cls.pip_check_patcher.start() + def setUp(self): + super().setUp() + self.mock_pip_check = self.pip_check_patcher.start() + self.mock_pip_install = self.pip_install_patcher.start() - @classmethod - def tearDownClass(cls): - cls.pip_check_patcher.start() - cls.pip_install_patcher.start() - cls.pkg_patcher.stop() + def tearDown(self): + super().tearDown() + self.pip_check_patcher.stop() + self.pip_install_patcher.stop() @patch("sys.argv", ["bootstrap", "-a", "pipenv"]) def test_run_unknown_cmd(self): @@ -73,18 +76,44 @@ def test_run_unknown_cmd(self): @patch("sys.argv", ["bootstrap", "-a", "requirements"]) def test_run_cmd_print(self): + self.pkg_patcher.start() with patch("sys.stdout", new=StringIO()) as fake_out: bootstrap.run() self.assertEqual( fake_out.getvalue(), "\n".join(self.installed_libraries) + "\n", ) + self.pkg_patcher.stop() @patch("sys.argv", ["bootstrap", "-a", "install"]) def test_run_cmd_install(self): + self.pkg_patcher.start() bootstrap.run() self.mock_pip_install.assert_has_calls( [call(i) for i in self.installed_libraries], any_order=True, ) - self.assertEqual(self.mock_pip_check.call_count, 1) + self.mock_pip_check.assert_called_once() + self.pkg_patcher.stop() + + @patch("sys.argv", ["bootstrap", "-a", "install"]) + def test_can_override_available_libraries(self): + bootstrap.run(libraries=[]) + self.mock_pip_install.assert_has_calls( + [call(i) for i in default_instrumentations], + any_order=True, + ) + self.mock_pip_check.assert_called_once() + + @patch("sys.argv", ["bootstrap", "-a", "install"]) + def test_can_override_available_default_instrumentations(self): + with patch( + "opentelemetry.instrumentation.bootstrap._is_installed", + return_value=True, + ): + bootstrap.run(default_instrumentations=[]) + self.mock_pip_install.assert_has_calls( + [call(i) for i in self.installed_libraries], + any_order=True, + ) + self.mock_pip_check.assert_called_once() From 5145a07fd1bda3db364b25c97756cb1661c9634a Mon Sep 17 00:00:00 2001 From: Erle Carrara Date: Thu, 24 Oct 2024 17:07:20 -0300 Subject: [PATCH 201/335] Support functools.partial functions in AsyncioInstrumentor.trace_to_thread (#2911) --- CHANGELOG.md | 3 ++ .../instrumentation/asyncio/__init__.py | 12 ++++--- .../tests/test_asyncio_to_thread.py | 35 +++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 028b4ee63e..0079547454 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2753](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2753)) - `opentelemetry-instrumentation-grpc` Fix grpc supported version ([#2845](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2845)) +- `opentelemetry-instrumentation-asyncio` fix `AttributeError` in + `AsyncioInstrumentor.trace_to_thread` when `func` is a `functools.partial` instance + ([#2911](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2911)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index a6cc6b044f..2d1b063dfd 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -78,6 +78,7 @@ def func(): """ import asyncio +import functools import sys from asyncio import futures from timeit import default_timer @@ -231,14 +232,15 @@ def wrap_taskgroup_create_task(method, instance, args, kwargs) -> None: def trace_to_thread(self, func: callable): """Trace a function.""" start = default_timer() + func_name = getattr(func, "__name__", None) + if func_name is None and isinstance(func, functools.partial): + func_name = func.func.__name__ span = ( - self._tracer.start_span( - f"{ASYNCIO_PREFIX} to_thread-" + func.__name__ - ) - if func.__name__ in self._to_thread_name_to_trace + self._tracer.start_span(f"{ASYNCIO_PREFIX} to_thread-" + func_name) + if func_name in self._to_thread_name_to_trace else None ) - attr = {"type": "to_thread", "name": func.__name__} + attr = {"type": "to_thread", "name": func_name} exception = None try: attr["state"] = "finished" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py index 3d795d8ae7..35191d3d03 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_to_thread.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio +import functools import sys from unittest import skipIf from unittest.mock import patch @@ -72,3 +73,37 @@ async def to_thread(): for point in metric.data.data_points: self.assertEqual(point.attributes["type"], "to_thread") self.assertEqual(point.attributes["name"], "multiply") + + @skipIf( + sys.version_info < (3, 9), "to_thread is only available in Python 3.9+" + ) + def test_to_thread_partial_func(self): + def multiply(x, y): + return x * y + + double = functools.partial(multiply, 2) + + async def to_thread(): + result = await asyncio.to_thread(double, 3) + assert result == 6 + + with self._tracer.start_as_current_span("root"): + asyncio.run(to_thread()) + spans = self.memory_exporter.get_finished_spans() + + self.assertEqual(len(spans), 2) + assert spans[0].name == "asyncio to_thread-multiply" + for metric in ( + self.memory_metrics_reader.get_metrics_data() + .resource_metrics[0] + .scope_metrics[0] + .metrics + ): + if metric.name == "asyncio.process.duration": + for point in metric.data.data_points: + self.assertEqual(point.attributes["type"], "to_thread") + self.assertEqual(point.attributes["name"], "multiply") + if metric.name == "asyncio.process.created": + for point in metric.data.data_points: + self.assertEqual(point.attributes["type"], "to_thread") + self.assertEqual(point.attributes["name"], "multiply") From 39bd7fa79acdb4ffe58f20ae371adcfc4e1b9b66 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 24 Oct 2024 22:19:29 +0200 Subject: [PATCH 202/335] opentelemetry-instrumentation: add unwrapping from dotted paths strings (#2919) --- CHANGELOG.md | 2 + .../opentelemetry/instrumentation/utils.py | 24 +++++- .../tests/test_utils.py | 83 +++++++++++++++++++ 3 files changed, 106 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0079547454..1a345d939a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2082](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2082)) - `opentelemetry-instrumentation-redis` Add additional attributes for methods create_index and search, rename those spans ([#2635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2635)) +- `opentelemetry-instrumentation` Add support for string based dotted module paths in unwrap + ([#2919](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2919)) ### Fixed diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index 73c000ee9c..a0d9ae18f9 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -14,8 +14,9 @@ import urllib.parse from contextlib import contextmanager +from importlib import import_module from re import escape, sub -from typing import Dict, Iterable, Sequence +from typing import Dict, Iterable, Sequence, Union from wrapt import ObjectProxy @@ -80,13 +81,30 @@ def http_status_to_status_code( return StatusCode.ERROR -def unwrap(obj, attr: str): +def unwrap(obj: Union[object, str], attr: str): """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it + The object containing the function to unwrap may be passed as dotted module path string. + Args: - obj: Object that holds a reference to the wrapped function + obj: Object that holds a reference to the wrapped function or dotted import path as string attr (str): Name of the wrapped function """ + if isinstance(obj, str): + try: + module_path, class_name = obj.rsplit(".", 1) + except ValueError as exc: + raise ImportError( + f"Cannot parse '{obj}' as dotted import path" + ) from exc + module = import_module(module_path) + try: + obj = getattr(module, class_name) + except AttributeError as exc: + raise ImportError( + f"Cannot import '{class_name}' from '{module}'" + ) from exc + func = getattr(obj, attr, None) if func and isinstance(func, ObjectProxy) and hasattr(func, "__wrapped__"): setattr(obj, attr, func.__wrapped__) diff --git a/opentelemetry-instrumentation/tests/test_utils.py b/opentelemetry-instrumentation/tests/test_utils.py index d3807a1bdb..5ddd45d692 100644 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ b/opentelemetry-instrumentation/tests/test_utils.py @@ -15,6 +15,8 @@ import unittest from http import HTTPStatus +from wrapt import ObjectProxy, wrap_function_wrapper + from opentelemetry.context import ( _SUPPRESS_HTTP_INSTRUMENTATION_KEY, _SUPPRESS_INSTRUMENTATION_KEY, @@ -29,10 +31,19 @@ is_instrumentation_enabled, suppress_http_instrumentation, suppress_instrumentation, + unwrap, ) from opentelemetry.trace import StatusCode +class WrappedClass: + def method(self): + pass + + def wrapper_method(self): + pass + + class TestUtils(unittest.TestCase): # See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status def test_http_status_to_status_code(self): @@ -240,3 +251,75 @@ def test_suppress_http_instrumentation_key(self): self.assertTrue(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY)) self.assertIsNone(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY)) + + +class UnwrapTestCase(unittest.TestCase): + @staticmethod + def _wrap_method(): + return wrap_function_wrapper( + WrappedClass, "method", WrappedClass.wrapper_method + ) + + def test_can_unwrap_object_attribute(self): + self._wrap_method() + instance = WrappedClass() + self.assertTrue(isinstance(instance.method, ObjectProxy)) + + unwrap(WrappedClass, "method") + self.assertFalse(isinstance(instance.method, ObjectProxy)) + + def test_can_unwrap_object_attribute_as_string(self): + self._wrap_method() + instance = WrappedClass() + self.assertTrue(isinstance(instance.method, ObjectProxy)) + + unwrap("tests.test_utils.WrappedClass", "method") + self.assertFalse(isinstance(instance.method, ObjectProxy)) + + def test_raises_import_error_if_path_not_well_formed(self): + self._wrap_method() + instance = WrappedClass() + self.assertTrue(isinstance(instance.method, ObjectProxy)) + + with self.assertRaisesRegex( + ImportError, "Cannot parse '' as dotted import path" + ): + unwrap("", "method") + + unwrap(WrappedClass, "method") + self.assertFalse(isinstance(instance.method, ObjectProxy)) + + def test_raises_import_error_if_cannot_find_module(self): + self._wrap_method() + instance = WrappedClass() + self.assertTrue(isinstance(instance.method, ObjectProxy)) + + with self.assertRaisesRegex(ImportError, "No module named 'does'"): + unwrap("does.not.exist.WrappedClass", "method") + + unwrap(WrappedClass, "method") + self.assertFalse(isinstance(instance.method, ObjectProxy)) + + def test_raises_import_error_if_cannot_find_object(self): + self._wrap_method() + instance = WrappedClass() + self.assertTrue(isinstance(instance.method, ObjectProxy)) + + with self.assertRaisesRegex( + ImportError, "Cannot import 'NotWrappedClass' from" + ): + unwrap("tests.test_utils.NotWrappedClass", "method") + + unwrap(WrappedClass, "method") + self.assertFalse(isinstance(instance.method, ObjectProxy)) + + # pylint: disable=no-self-use + def test_does_nothing_if_cannot_find_attribute(self): + instance = WrappedClass() + unwrap(instance, "method_not_found") + + def test_does_nothing_if_attribute_is_not_from_wrapt(self): + instance = WrappedClass() + self.assertFalse(isinstance(instance.method, ObjectProxy)) + unwrap(WrappedClass, "method") + self.assertFalse(isinstance(instance.method, ObjectProxy)) From e49806ea35318ca8118767bd372df3bfae01fbb7 Mon Sep 17 00:00:00 2001 From: Sai Chander Date: Fri, 25 Oct 2024 04:46:25 +0800 Subject: [PATCH 203/335] Configurable Middleware Position for Django Instrumentation (#2912) --- CHANGELOG.md | 2 + .../instrumentation/django/__init__.py | 36 ++++++++++++++++- .../tests/test_middleware.py | 40 +++++++++++++++++++ .../tests/test_sqlcommenter.py | 31 ++++++++++++++ 4 files changed, 107 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a345d939a..a43ec36b00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -417,6 +417,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1879](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1879)) - Add optional distro and configurator selection for auto-instrumentation ([#1823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1823)) +- `opentelemetry-instrumentation-django` - Add option to add Opentelemetry middleware at specific position in middleware chain + ([#2912]https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2912) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py index d37c45993c..e5851a17c2 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py @@ -285,6 +285,30 @@ def _get_django_middleware_setting() -> str: return "MIDDLEWARE" +def _get_django_otel_middleware_position( + middleware_length, default_middleware_position=0 +): + otel_position = environ.get("OTEL_PYTHON_DJANGO_MIDDLEWARE_POSITION") + try: + middleware_position = int(otel_position) + except (ValueError, TypeError): + _logger.debug( + "Invalid OTEL_PYTHON_DJANGO_MIDDLEWARE_POSITION value: (%s). Using default position: %d.", + otel_position, + default_middleware_position, + ) + middleware_position = default_middleware_position + + if middleware_position < 0 or middleware_position > middleware_length: + _logger.debug( + "Middleware position %d is out of range (0-%d). Using 0 as the position", + middleware_position, + middleware_length, + ) + middleware_position = 0 + return middleware_position + + class DjangoInstrumentor(BaseInstrumentor): """An instrumentor for Django @@ -388,10 +412,18 @@ def _instrument(self, **kwargs): is_sql_commentor_enabled = kwargs.pop("is_sql_commentor_enabled", None) + middleware_position = _get_django_otel_middleware_position( + len(settings_middleware), kwargs.pop("middleware_position", 0) + ) + if is_sql_commentor_enabled: - settings_middleware.insert(0, self._sql_commenter_middleware) + settings_middleware.insert( + middleware_position, self._sql_commenter_middleware + ) - settings_middleware.insert(0, self._opentelemetry_middleware) + settings_middleware.insert( + middleware_position, self._opentelemetry_middleware + ) setattr(settings, _middleware_setting, settings_middleware) diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index 85ebbd747f..1c85935892 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -157,6 +157,46 @@ def tearDownClass(cls): super().tearDownClass() conf.settings = conf.LazySettings() + def test_middleware_added_at_position(self): + _django_instrumentor.uninstrument() + if DJANGO_2_0: + middleware = conf.settings.MIDDLEWARE + else: + middleware = conf.settings.MIDDLEWARE_CLASSES + # adding two dummy middlewares + temprory_middelware = "django.utils.deprecation.MiddlewareMixin" + middleware.append(temprory_middelware) + middleware.append(temprory_middelware) + + middleware_position = 1 + _django_instrumentor.instrument( + middleware_position=middleware_position + ) + self.assertEqual( + middleware[middleware_position], + "opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware", + ) + + def test_middleware_added_at_position_if_wrong_position(self): + _django_instrumentor.uninstrument() + if DJANGO_2_0: + middleware = conf.settings.MIDDLEWARE + else: + middleware = conf.settings.MIDDLEWARE_CLASSES + # adding middleware + temprory_middelware = "django.utils.deprecation.MiddlewareMixin" + middleware.append(temprory_middelware) + middleware_position = ( + 756 # wrong position out of bound of middleware length + ) + _django_instrumentor.instrument( + middleware_position=middleware_position + ) + self.assertEqual( + middleware[0], + "opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware", + ) + def test_templated_route_get(self): Client().get("/route/2020/template/") diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_sqlcommenter.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_sqlcommenter.py index f9b8ed5233..eec02d7a54 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_sqlcommenter.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_sqlcommenter.py @@ -72,6 +72,37 @@ def test_middleware_added(self, sqlcommenter_middleware): in middleware ) + @patch( + "opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware.SqlCommenter" + ) + def test_middleware_added_at_position(self, sqlcommenter_middleware): + _django_instrumentor.uninstrument() + if DJANGO_2_0: + middleware = conf.settings.MIDDLEWARE + else: + middleware = conf.settings.MIDDLEWARE_CLASSES + + # adding two dummy middlewares + temprory_middelware = "django.utils.deprecation.MiddlewareMixin" + middleware.append(temprory_middelware) + middleware.append(temprory_middelware) + + middleware_position = 1 + _django_instrumentor.instrument( + is_sql_commentor_enabled=True, + middleware_position=middleware_position, + ) + instance = sqlcommenter_middleware.return_value + instance.get_response = HttpResponse() + self.assertEqual( + middleware[middleware_position], + "opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware", + ) + self.assertEqual( + middleware[middleware_position + 1], + "opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware.SqlCommenter", + ) + @patch( "opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware._get_opentelemetry_values" ) From 779ec9eb93298b47d1038b4dc5fcf35b86853a0c Mon Sep 17 00:00:00 2001 From: "Mengyi Zhou (bjrara)" Date: Fri, 25 Oct 2024 12:00:37 -0700 Subject: [PATCH 204/335] Fix unit in system metrics (#2922) --- CHANGELOG.md | 2 ++ .../instrumentation/system_metrics/__init__.py | 18 +++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a43ec36b00..f3682d4a70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874)) - `opentelemetry-instrumentation-confluent-kafka` Fix to allow `topic` to be extracted from `kwargs` in `produce()` ([#2901])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2901) +- `opentelemetry-instrumentation-system-metrics` Update metric units to conform to UCUM conventions. + ([#2922](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2922)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index 1b9a36c4cb..0953e65fb5 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -190,7 +190,7 @@ def _instrument(self, **kwargs): name="system.cpu.time", callbacks=[self._get_system_cpu_time], description="System CPU time", - unit="seconds", + unit="s", ) if "system.cpu.utilization" in self._config: @@ -206,7 +206,7 @@ def _instrument(self, **kwargs): name="system.memory.usage", callbacks=[self._get_system_memory_usage], description="System memory usage", - unit="bytes", + unit="By", ) if "system.memory.utilization" in self._config: @@ -257,7 +257,7 @@ def _instrument(self, **kwargs): name="system.disk.io", callbacks=[self._get_system_disk_io], description="System disk IO", - unit="bytes", + unit="By", ) if "system.disk.operations" in self._config: @@ -273,7 +273,7 @@ def _instrument(self, **kwargs): name="system.disk.time", callbacks=[self._get_system_disk_time], description="System disk time", - unit="seconds", + unit="s", ) # TODO Add _get_system_filesystem_usage @@ -282,7 +282,7 @@ def _instrument(self, **kwargs): # callback=self._get_system_filesystem_usage, # name="system.filesystem.usage", # description="System filesystem usage", - # unit="bytes", + # unit="By", # value_type=int, # ) @@ -327,7 +327,7 @@ def _instrument(self, **kwargs): name="system.network.io", callbacks=[self._get_system_network_io], description="System network io", - unit="bytes", + unit="By", ) if "system.network.connections" in self._config: @@ -350,7 +350,7 @@ def _instrument(self, **kwargs): name=f"process.runtime.{self._python_implementation}.memory", callbacks=[self._get_runtime_memory], description=f"Runtime {self._python_implementation} memory", - unit="bytes", + unit="By", ) if "process.runtime.cpu.time" in self._config: @@ -358,7 +358,7 @@ def _instrument(self, **kwargs): name=f"process.runtime.{self._python_implementation}.cpu_time", callbacks=[self._get_runtime_cpu_time], description=f"Runtime {self._python_implementation} CPU time", - unit="seconds", + unit="s", ) if "process.runtime.gc_count" in self._config: @@ -371,7 +371,7 @@ def _instrument(self, **kwargs): name=f"process.runtime.{self._python_implementation}.gc_count", callbacks=[self._get_runtime_gc_count], description=f"Runtime {self._python_implementation} GC count", - unit="bytes", + unit="By", ) if "process.runtime.thread_count" in self._config: From 8582da5b8decd99f3780e820b5652d4c72b7a953 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 25 Oct 2024 21:25:51 +0200 Subject: [PATCH 205/335] opentelemetry-instrumentation: don't fail if an instrumentor raises ImportError (#2923) --- CHANGELOG.md | 2 + .../auto_instrumentation/_load.py | 11 ++++ .../tests/auto_instrumentation/test_load.py | 64 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3682d4a70..867f30afbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Deprecation of pkg_resource in favor of importlib.metadata ([#2871](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2871)) +- `opentelemetry-instrumentation` Don't fail distro loading if instrumentor raises ImportError, instead skip them + ([#2923](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2923)) ## Version 1.27.0/0.48b0 (2024-08-28) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py index acc81c701c..3d602b2a1d 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py @@ -113,6 +113,17 @@ def _load_instrumentors(distro): # tell instrumentation to not run dep checks again as we already did it above distro.load_instrumentor(entry_point, skip_dep_check=True) _logger.debug("Instrumented %s", entry_point.name) + except ImportError: + # in scenarios using the kubernetes operator to do autoinstrumentation some + # instrumentors (usually requiring binary extensions) may fail to load + # because the injected autoinstrumentation code does not match the application + # environment regarding python version, libc, etc... In this case it's better + # to skip the single instrumentation rather than failing to load everything + # so treat differently ImportError than the rest of exceptions + _logger.exception( + "Importing of %s failed, skipping it", entry_point.name + ) + continue except Exception as exc: # pylint: disable=broad-except _logger.exception("Instrumenting of %s failed", entry_point.name) raise exc diff --git a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py index 2d8538b5b3..ce9abe1365 100644 --- a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py +++ b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py @@ -310,6 +310,70 @@ def test_load_instrumentors_dep_conflict(self, iter_mock, dep_mock): # pylint: ) distro_mock.load_instrumentor.assert_called_once() + @patch( + "opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts" + ) + @patch( + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" + ) + def test_load_instrumentors_import_error_does_not_stop_everything( + self, iter_mock, dep_mock + ): + ep_mock1 = Mock(name="instr1") + ep_mock2 = Mock(name="instr2") + + distro_mock = Mock() + distro_mock.load_instrumentor.side_effect = [ImportError, None] + + # Mock entry points in order + iter_mock.side_effect = [ + (), + (ep_mock1, ep_mock2), + (), + ] + dep_mock.return_value = None + + _load._load_instrumentors(distro_mock) + + distro_mock.load_instrumentor.assert_has_calls( + [ + call(ep_mock1, skip_dep_check=True), + call(ep_mock2, skip_dep_check=True), + ] + ) + self.assertEqual(distro_mock.load_instrumentor.call_count, 2) + + @patch( + "opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts" + ) + @patch( + "opentelemetry.instrumentation.auto_instrumentation._load.entry_points" + ) + def test_load_instrumentors_raises_exception(self, iter_mock, dep_mock): + ep_mock1 = Mock(name="instr1") + ep_mock2 = Mock(name="instr2") + + distro_mock = Mock() + distro_mock.load_instrumentor.side_effect = [ValueError, None] + + # Mock entry points in order + iter_mock.side_effect = [ + (), + (ep_mock1, ep_mock2), + (), + ] + dep_mock.return_value = None + + with self.assertRaises(ValueError): + _load._load_instrumentors(distro_mock) + + distro_mock.load_instrumentor.assert_has_calls( + [ + call(ep_mock1, skip_dep_check=True), + ] + ) + self.assertEqual(distro_mock.load_instrumentor.call_count, 1) + def test_load_instrumentors_no_entry_point_mocks(self): distro_mock = Mock() _load._load_instrumentors(distro_mock) From 7cbe58691af05e90cefb70bcbd5b03b7b3385f2c Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 28 Oct 2024 17:40:25 +0100 Subject: [PATCH 206/335] opentelemetry-instrumentation-celery: don't detach a None token (#2927) --- CHANGELOG.md | 2 + .../instrumentation/celery/__init__.py | 5 ++- .../tests/test_tasks.py | 39 ++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 867f30afbb..ed4671d559 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2901])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2901) - `opentelemetry-instrumentation-system-metrics` Update metric units to conform to UCUM conventions. ([#2922](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2922)) +- `opentelemetry-instrumentation-celery` Don't detach context without a None token + ([#2927](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2927)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py index 39b3bffe60..908f158507 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py @@ -213,7 +213,10 @@ def _trace_postrun(self, *args, **kwargs): self.update_task_duration_time(task_id) labels = {"task": task.name, "worker": task.request.hostname} self._record_histograms(task_id, labels) - context_api.detach(token) + # if the process sending the task is not instrumented + # there's no incoming context and no token to detach + if token is not None: + context_api.detach(token) def _trace_before_publish(self, *args, **kwargs): task = utils.retrieve_task_from_sender(kwargs) diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py index 0dc668b112..c68b1bc758 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py @@ -15,8 +15,11 @@ import threading import time +from wrapt import wrap_function_wrapper + from opentelemetry import baggage, context -from opentelemetry.instrumentation.celery import CeleryInstrumentor +from opentelemetry.instrumentation.celery import CeleryInstrumentor, utils +from opentelemetry.instrumentation.utils import unwrap from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind, StatusCode @@ -185,6 +188,40 @@ def test_baggage(self): self.assertEqual(task.result, {"key": "value"}) + def test_task_not_instrumented_does_not_raise(self): + def _retrieve_context_wrapper_none_token( + wrapped, instance, args, kwargs + ): + ctx = wrapped(*args, **kwargs) + if ctx is None: + return ctx + span, activation, _ = ctx + return span, activation, None + + wrap_function_wrapper( + utils, + "retrieve_context", + _retrieve_context_wrapper_none_token, + ) + + CeleryInstrumentor().instrument() + + result = task_add.delay(1, 2) + + timeout = time.time() + 60 * 1 # 1 minutes from now + while not result.ready(): + if time.time() > timeout: + break + time.sleep(0.05) + + spans = self.sorted_spans(self.memory_exporter.get_finished_spans()) + self.assertEqual(len(spans), 2) + + # TODO: assert we don't have "TypeError: expected an instance of Token, got None" in logs + self.assertTrue(result) + + unwrap(utils, "retrieve_context") + class TestCelerySignatureTask(TestBase): def setUp(self): From f6b68d0c024cf40d15c08062a18bf70ea73847e6 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 29 Oct 2024 21:33:35 +0100 Subject: [PATCH 207/335] httpx: rewrite patching to use wrapt instead of subclassing client (#2909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit httpx: rewrote patching to use wrapt instead of subclassing client Porting of httpx instrumentation to patch async transport methods instead of substituting the client. That is because the current approach will instrument httpx by instantianting another client with a custom transport class and this will race with code already subclassing. This one uses wrapt to patch the default httpx transport classes. --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- CHANGELOG.md | 2 + .../pyproject.toml | 1 + .../instrumentation/httpx/__init__.py | 378 +++++++++++++----- .../tests/test_httpx_integration.py | 99 +++-- 4 files changed, 350 insertions(+), 130 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed4671d559..7597e60641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2871](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2871)) - `opentelemetry-instrumentation` Don't fail distro loading if instrumentor raises ImportError, instead skip them ([#2923](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2923)) +- `opentelemetry-instrumentation-httpx` Rewrote instrumentation to use wrapt instead of subclassing + ([#2909](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2909)) ## Version 1.27.0/0.48b0 (2024-08-28) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 599091716b..c986fac4a1 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.49b0.dev", "opentelemetry-semantic-conventions == 0.49b0.dev", "opentelemetry-util-http == 0.49b0.dev", + "wrapt >= 1.0.0, < 2.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index b9b9a31d3e..d3a2cecfe6 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=too-many-lines """ Usage ----- @@ -194,9 +195,11 @@ async def async_response_hook(span, request, response): import logging import typing from asyncio import iscoroutinefunction +from functools import partial from types import TracebackType import httpx +from wrapt import wrap_function_wrapper from opentelemetry.instrumentation._semconv import ( _get_schema_url, @@ -217,6 +220,7 @@ async def async_response_hook(span, request, response): from opentelemetry.instrumentation.utils import ( http_status_to_status_code, is_http_instrumentation_enabled, + unwrap, ) from opentelemetry.propagate import inject from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE @@ -731,44 +735,211 @@ def _instrument(self, **kwargs): ``async_request_hook``: Async ``request_hook`` for ``httpx.AsyncClient`` ``async_response_hook``: Async``response_hook`` for ``httpx.AsyncClient`` """ - self._original_client = httpx.Client - self._original_async_client = httpx.AsyncClient + tracer_provider = kwargs.get("tracer_provider") request_hook = kwargs.get("request_hook") response_hook = kwargs.get("response_hook") async_request_hook = kwargs.get("async_request_hook") - async_response_hook = kwargs.get("async_response_hook") - if callable(request_hook): - _InstrumentedClient._request_hook = request_hook - if callable(async_request_hook) and iscoroutinefunction( + async_request_hook = ( async_request_hook - ): - _InstrumentedAsyncClient._request_hook = async_request_hook - if callable(response_hook): - _InstrumentedClient._response_hook = response_hook - if callable(async_response_hook) and iscoroutinefunction( + if iscoroutinefunction(async_request_hook) + else None + ) + async_response_hook = kwargs.get("async_response_hook") + async_response_hook = ( async_response_hook - ): - _InstrumentedAsyncClient._response_hook = async_response_hook - tracer_provider = kwargs.get("tracer_provider") - _InstrumentedClient._tracer_provider = tracer_provider - _InstrumentedAsyncClient._tracer_provider = tracer_provider - # Intentionally using a private attribute here, see: - # https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538#discussion_r1610603719 - httpx.Client = httpx._api.Client = _InstrumentedClient - httpx.AsyncClient = _InstrumentedAsyncClient + if iscoroutinefunction(async_response_hook) + else None + ) + + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + tracer = get_tracer( + __name__, + instrumenting_library_version=__version__, + tracer_provider=tracer_provider, + schema_url=_get_schema_url(sem_conv_opt_in_mode), + ) + + wrap_function_wrapper( + "httpx", + "HTTPTransport.handle_request", + partial( + self._handle_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + request_hook=request_hook, + response_hook=response_hook, + ), + ) + wrap_function_wrapper( + "httpx", + "AsyncHTTPTransport.handle_async_request", + partial( + self._handle_async_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + async_request_hook=async_request_hook, + async_response_hook=async_response_hook, + ), + ) def _uninstrument(self, **kwargs): - httpx.Client = httpx._api.Client = self._original_client - httpx.AsyncClient = self._original_async_client - _InstrumentedClient._tracer_provider = None - _InstrumentedClient._request_hook = None - _InstrumentedClient._response_hook = None - _InstrumentedAsyncClient._tracer_provider = None - _InstrumentedAsyncClient._request_hook = None - _InstrumentedAsyncClient._response_hook = None + unwrap(httpx.HTTPTransport, "handle_request") + unwrap(httpx.AsyncHTTPTransport, "handle_async_request") @staticmethod + def _handle_request_wrapper( # pylint: disable=too-many-locals + wrapped, + instance, + args, + kwargs, + tracer, + sem_conv_opt_in_mode, + request_hook, + response_hook, + ): + if not is_http_instrumentation_enabled(): + return wrapped(*args, **kwargs) + + method, url, headers, stream, extensions = _extract_parameters( + args, kwargs + ) + method_original = method.decode() + span_name = _get_default_span_name(method_original) + span_attributes = {} + # apply http client response attributes according to semconv + _apply_request_client_attributes_to_span( + span_attributes, + url, + method_original, + sem_conv_opt_in_mode, + ) + + request_info = RequestInfo(method, url, headers, stream, extensions) + + with tracer.start_as_current_span( + span_name, kind=SpanKind.CLIENT, attributes=span_attributes + ) as span: + exception = None + if callable(request_hook): + request_hook(span, request_info) + + _inject_propagation_headers(headers, args, kwargs) + + try: + response = wrapped(*args, **kwargs) + except Exception as exc: # pylint: disable=W0703 + exception = exc + response = getattr(exc, "response", None) + + if isinstance(response, (httpx.Response, tuple)): + status_code, headers, stream, extensions, http_version = ( + _extract_response(response) + ) + + if span.is_recording(): + # apply http client response attributes according to semconv + _apply_response_client_attributes_to_span( + span, + status_code, + http_version, + sem_conv_opt_in_mode, + ) + if callable(response_hook): + response_hook( + span, + request_info, + ResponseInfo(status_code, headers, stream, extensions), + ) + + if exception: + if span.is_recording() and _report_new(sem_conv_opt_in_mode): + span.set_attribute( + ERROR_TYPE, type(exception).__qualname__ + ) + raise exception.with_traceback(exception.__traceback__) + + return response + + @staticmethod + async def _handle_async_request_wrapper( # pylint: disable=too-many-locals + wrapped, + instance, + args, + kwargs, + tracer, + sem_conv_opt_in_mode, + async_request_hook, + async_response_hook, + ): + if not is_http_instrumentation_enabled(): + return await wrapped(*args, **kwargs) + + method, url, headers, stream, extensions = _extract_parameters( + args, kwargs + ) + method_original = method.decode() + span_name = _get_default_span_name(method_original) + span_attributes = {} + # apply http client response attributes according to semconv + _apply_request_client_attributes_to_span( + span_attributes, + url, + method_original, + sem_conv_opt_in_mode, + ) + + request_info = RequestInfo(method, url, headers, stream, extensions) + + with tracer.start_as_current_span( + span_name, kind=SpanKind.CLIENT, attributes=span_attributes + ) as span: + exception = None + if callable(async_request_hook): + await async_request_hook(span, request_info) + + _inject_propagation_headers(headers, args, kwargs) + + try: + response = await wrapped(*args, **kwargs) + except Exception as exc: # pylint: disable=W0703 + exception = exc + response = getattr(exc, "response", None) + + if isinstance(response, (httpx.Response, tuple)): + status_code, headers, stream, extensions, http_version = ( + _extract_response(response) + ) + + if span.is_recording(): + # apply http client response attributes according to semconv + _apply_response_client_attributes_to_span( + span, + status_code, + http_version, + sem_conv_opt_in_mode, + ) + + if callable(async_response_hook): + await async_response_hook( + span, + request_info, + ResponseInfo(status_code, headers, stream, extensions), + ) + + if exception: + if span.is_recording() and _report_new(sem_conv_opt_in_mode): + span.set_attribute( + ERROR_TYPE, type(exception).__qualname__ + ) + raise exception.with_traceback(exception.__traceback__) + + return response + def instrument_client( + self, client: typing.Union[httpx.Client, httpx.AsyncClient], tracer_provider: TracerProvider = None, request_hook: typing.Union[ @@ -788,67 +959,88 @@ def instrument_client( response_hook: A hook that receives the span, request, and response that is called right before the span ends """ - # pylint: disable=protected-access - if not hasattr(client, "_is_instrumented_by_opentelemetry"): - client._is_instrumented_by_opentelemetry = False - if not client._is_instrumented_by_opentelemetry: - if isinstance(client, httpx.Client): - client._original_transport = client._transport - client._original_mounts = client._mounts.copy() - transport = client._transport or httpx.HTTPTransport() - client._transport = SyncOpenTelemetryTransport( - transport, - tracer_provider=tracer_provider, - request_hook=request_hook, - response_hook=response_hook, - ) - client._is_instrumented_by_opentelemetry = True - client._mounts.update( - { - url_pattern: ( - SyncOpenTelemetryTransport( - transport, - tracer_provider=tracer_provider, - request_hook=request_hook, - response_hook=response_hook, - ) - if transport is not None - else transport - ) - for url_pattern, transport in client._original_mounts.items() - } - ) + if getattr(client, "_is_instrumented_by_opentelemetry", False): + _logger.warning( + "Attempting to instrument Httpx client while already instrumented" + ) + return - if isinstance(client, httpx.AsyncClient): - transport = client._transport or httpx.AsyncHTTPTransport() - client._original_mounts = client._mounts.copy() - client._transport = AsyncOpenTelemetryTransport( - transport, - tracer_provider=tracer_provider, + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + tracer = get_tracer( + __name__, + instrumenting_library_version=__version__, + tracer_provider=tracer_provider, + schema_url=_get_schema_url(sem_conv_opt_in_mode), + ) + + if iscoroutinefunction(request_hook): + async_request_hook = request_hook + request_hook = None + else: + # request_hook already set + async_request_hook = None + + if iscoroutinefunction(response_hook): + async_response_hook = response_hook + response_hook = None + else: + # response_hook already set + async_response_hook = None + + if hasattr(client._transport, "handle_request"): + wrap_function_wrapper( + client._transport, + "handle_request", + partial( + self._handle_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, request_hook=request_hook, response_hook=response_hook, + ), + ) + for transport in client._mounts.values(): + wrap_function_wrapper( + transport, + "handle_request", + partial( + self._handle_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + request_hook=request_hook, + response_hook=response_hook, + ), ) - client._is_instrumented_by_opentelemetry = True - client._mounts.update( - { - url_pattern: ( - AsyncOpenTelemetryTransport( - transport, - tracer_provider=tracer_provider, - request_hook=request_hook, - response_hook=response_hook, - ) - if transport is not None - else transport - ) - for url_pattern, transport in client._original_mounts.items() - } - ) - else: - _logger.warning( - "Attempting to instrument Httpx client while already instrumented" + client._is_instrumented_by_opentelemetry = True + if hasattr(client._transport, "handle_async_request"): + wrap_function_wrapper( + client._transport, + "handle_async_request", + partial( + self._handle_async_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + async_request_hook=async_request_hook, + async_response_hook=async_response_hook, + ), ) + for transport in client._mounts.values(): + wrap_function_wrapper( + transport, + "handle_async_request", + partial( + self._handle_async_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + async_request_hook=async_request_hook, + async_response_hook=async_response_hook, + ), + ) + client._is_instrumented_by_opentelemetry = True @staticmethod def uninstrument_client( @@ -859,15 +1051,13 @@ def uninstrument_client( Args: client: The httpx Client or AsyncClient instance """ - if hasattr(client, "_original_transport"): - client._transport = client._original_transport - del client._original_transport + if hasattr(client._transport, "handle_request"): + unwrap(client._transport, "handle_request") + for transport in client._mounts.values(): + unwrap(transport, "handle_request") + client._is_instrumented_by_opentelemetry = False + elif hasattr(client._transport, "handle_async_request"): + unwrap(client._transport, "handle_async_request") + for transport in client._mounts.values(): + unwrap(transport, "handle_async_request") client._is_instrumented_by_opentelemetry = False - if hasattr(client, "_original_mounts"): - client._mounts = client._original_mounts.copy() - del client._original_mounts - else: - _logger.warning( - "Attempting to uninstrument Httpx " - "client while already uninstrumented" - ) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 0d055515e0..07699700c4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -21,6 +21,7 @@ import httpx import respx +from wrapt import ObjectProxy import opentelemetry.instrumentation.httpx from opentelemetry import trace @@ -171,6 +172,7 @@ def tearDown(self): super().tearDown() self.env_patch.stop() respx.stop() + HTTPXClientInstrumentor().uninstrument() def assert_span( self, exporter: "SpanExporter" = None, num_spans: int = 1 @@ -204,7 +206,7 @@ def test_basic(self): self.assertEqual(span.name, "GET") self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: self.URL, @@ -228,7 +230,7 @@ def test_nonstandard_http_method(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) self.assertEqual(span.name, "HTTP") self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "_OTHER", SpanAttributes.HTTP_URL: self.URL, @@ -252,7 +254,7 @@ def test_nonstandard_http_method_new_semconv(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) self.assertEqual(span.name, "HTTP") self.assertEqual( - span.attributes, + dict(span.attributes), { HTTP_REQUEST_METHOD: "_OTHER", URL_FULL: self.URL, @@ -292,7 +294,7 @@ def test_basic_new_semconv(self): SpanAttributes.SCHEMA_URL, ) self.assertEqual( - span.attributes, + dict(span.attributes), { HTTP_REQUEST_METHOD: "GET", URL_FULL: url, @@ -327,7 +329,7 @@ def test_basic_both_semconv(self): ) self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", HTTP_REQUEST_METHOD: "GET", @@ -454,7 +456,7 @@ def test_requests_500_error(self): span = self.assert_span() self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: self.URL, @@ -510,7 +512,7 @@ def test_requests_timeout_exception_new_semconv(self): span = self.assert_span() self.assertEqual( - span.attributes, + dict(span.attributes), { HTTP_REQUEST_METHOD: "GET", URL_FULL: url, @@ -531,7 +533,7 @@ def test_requests_timeout_exception_both_semconv(self): span = self.assert_span() self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", HTTP_REQUEST_METHOD: "GET", @@ -632,7 +634,7 @@ def test_response_hook(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: self.URL, @@ -741,8 +743,10 @@ def create_proxy_transport(self, url: str): def setUp(self): super().setUp() - HTTPXClientInstrumentor().instrument() self.client = self.create_client() + HTTPXClientInstrumentor().instrument_client(self.client) + + def tearDown(self): HTTPXClientInstrumentor().uninstrument() def create_proxy_mounts(self): @@ -755,14 +759,25 @@ def create_proxy_mounts(self): ), } - def assert_proxy_mounts(self, mounts, num_mounts, transport_type): + def assert_proxy_mounts(self, mounts, num_mounts, transport_type=None): self.assertEqual(len(mounts), num_mounts) for transport in mounts: with self.subTest(transport): - self.assertIsInstance( - transport, - transport_type, - ) + if transport_type: + self.assertIsInstance( + transport, + transport_type, + ) + else: + handler = getattr(transport, "handle_request", None) + if not handler: + handler = getattr( + transport, "handle_async_request" + ) + self.assertTrue( + isinstance(handler, ObjectProxy) + and getattr(handler, "__wrapped__") + ) def test_custom_tracer_provider(self): resource = resources.Resource.create({}) @@ -778,7 +793,6 @@ def test_custom_tracer_provider(self): self.assertEqual(result.text, "Hello!") span = self.assert_span(exporter=exporter) self.assertIs(span.resource, resource) - HTTPXClientInstrumentor().uninstrument() def test_response_hook(self): response_hook_key = ( @@ -797,7 +811,7 @@ def test_response_hook(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: self.URL, @@ -805,7 +819,6 @@ def test_response_hook(self): HTTP_RESPONSE_BODY: "Hello!", }, ) - HTTPXClientInstrumentor().uninstrument() def test_response_hook_sync_async_kwargs(self): HTTPXClientInstrumentor().instrument( @@ -819,7 +832,7 @@ def test_response_hook_sync_async_kwargs(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual( - span.attributes, + dict(span.attributes), { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: self.URL, @@ -827,7 +840,6 @@ def test_response_hook_sync_async_kwargs(self): HTTP_RESPONSE_BODY: "Hello!", }, ) - HTTPXClientInstrumentor().uninstrument() def test_request_hook(self): request_hook_key = ( @@ -846,7 +858,6 @@ def test_request_hook(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual(span.name, "GET" + self.URL) - HTTPXClientInstrumentor().uninstrument() def test_request_hook_sync_async_kwargs(self): HTTPXClientInstrumentor().instrument( @@ -860,7 +871,6 @@ def test_request_hook_sync_async_kwargs(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual(span.name, "GET" + self.URL) - HTTPXClientInstrumentor().uninstrument() def test_request_hook_no_span_update(self): HTTPXClientInstrumentor().instrument( @@ -873,7 +883,6 @@ def test_request_hook_no_span_update(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual(span.name, "GET") - HTTPXClientInstrumentor().uninstrument() def test_not_recording(self): with mock.patch("opentelemetry.trace.INVALID_SPAN") as mock_span: @@ -891,7 +900,6 @@ def test_not_recording(self): self.assertTrue(mock_span.is_recording.called) self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) - HTTPXClientInstrumentor().uninstrument() def test_suppress_instrumentation_new_client(self): HTTPXClientInstrumentor().instrument() @@ -901,7 +909,6 @@ def test_suppress_instrumentation_new_client(self): self.assertEqual(result.text, "Hello!") self.assert_span(num_spans=0) - HTTPXClientInstrumentor().uninstrument() def test_instrument_client(self): client = self.create_client() @@ -929,8 +936,6 @@ def test_instrumentation_without_client(self): self.URL, ) - HTTPXClientInstrumentor().uninstrument() - def test_uninstrument(self): HTTPXClientInstrumentor().instrument() HTTPXClientInstrumentor().uninstrument() @@ -980,9 +985,7 @@ def test_instrument_proxy(self): self.assert_proxy_mounts( client._mounts.values(), 2, - (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), ) - HTTPXClientInstrumentor().uninstrument() def test_instrument_client_with_proxy(self): proxy_mounts = self.create_proxy_mounts() @@ -999,7 +1002,6 @@ def test_instrument_client_with_proxy(self): self.assert_proxy_mounts( client._mounts.values(), 2, - (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), ) HTTPXClientInstrumentor().uninstrument_client(client) @@ -1010,7 +1012,6 @@ def test_uninstrument_client_with_proxy(self): self.assert_proxy_mounts( client._mounts.values(), 2, - (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), ) HTTPXClientInstrumentor().uninstrument_client(client) @@ -1180,6 +1181,21 @@ def perform_request( def create_proxy_transport(self, url): return httpx.HTTPTransport(proxy=httpx.Proxy(url)) + def test_can_instrument_subclassed_client(self): + class CustomClient(httpx.Client): + pass + + client = CustomClient() + self.assertFalse( + isinstance(client._transport.handle_request, ObjectProxy) + ) + + HTTPXClientInstrumentor().instrument() + + self.assertTrue( + isinstance(client._transport.handle_request, ObjectProxy) + ) + class TestAsyncInstrumentationIntegration(BaseTestCases.BaseInstrumentorTest): response_hook = staticmethod(_async_response_hook) @@ -1188,10 +1204,8 @@ class TestAsyncInstrumentationIntegration(BaseTestCases.BaseInstrumentorTest): def setUp(self): super().setUp() - HTTPXClientInstrumentor().instrument() - self.client = self.create_client() self.client2 = self.create_client() - HTTPXClientInstrumentor().uninstrument() + HTTPXClientInstrumentor().instrument_client(self.client2) def create_client( self, @@ -1245,7 +1259,6 @@ def test_async_response_hook_does_nothing_if_not_coroutine(self): SpanAttributes.HTTP_STATUS_CODE: 200, }, ) - HTTPXClientInstrumentor().uninstrument() def test_async_request_hook_does_nothing_if_not_coroutine(self): HTTPXClientInstrumentor().instrument( @@ -1258,4 +1271,18 @@ def test_async_request_hook_does_nothing_if_not_coroutine(self): self.assertEqual(result.text, "Hello!") span = self.assert_span() self.assertEqual(span.name, "GET") - HTTPXClientInstrumentor().uninstrument() + + def test_can_instrument_subclassed_async_client(self): + class CustomAsyncClient(httpx.AsyncClient): + pass + + client = CustomAsyncClient() + self.assertFalse( + isinstance(client._transport.handle_async_request, ObjectProxy) + ) + + HTTPXClientInstrumentor().instrument() + + self.assertTrue( + isinstance(client._transport.handle_async_request, ObjectProxy) + ) From a940fc4a65b6033d525e0e30b47485ad135aa617 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:46:11 -0700 Subject: [PATCH 208/335] Add DB-API instrumentor support for MySQL driver sqlcommenting (#2897) --- CHANGELOG.md | 2 + .../instrumentation/dbapi/__init__.py | 99 +++++++-- .../tests/test_dbapi_integration.py | 191 +++++++++++++++++- 3 files changed, 275 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7597e60641..29a34bae1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2922](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2922)) - `opentelemetry-instrumentation-celery` Don't detach context without a None token ([#2927](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2927)) +- `opentelemetry-instrumentation-dbapi` sqlcommenter key values created from PostgreSQL, MySQL systems + ([#2897](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2897)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index 0857d2989b..fc3911f744 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -53,6 +53,11 @@ ) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import SpanKind, TracerProvider, get_tracer +from opentelemetry.util._importlib_metadata import version as util_version + +_DB_DRIVER_ALIASES = { + "MySQLdb": "mysqlclient", +} _logger = logging.getLogger(__name__) @@ -275,6 +280,70 @@ def __init__( self.name = "" self.database = "" self.connect_module = connect_module + self.commenter_data = self.calculate_commenter_data() + + def _get_db_version( + self, + db_driver, + ): + if db_driver in _DB_DRIVER_ALIASES: + return util_version(_DB_DRIVER_ALIASES[db_driver]) + db_version = "" + try: + db_version = self.connect_module.__version__ + except AttributeError: + db_version = "unknown" + return db_version + + def calculate_commenter_data( + self, + ): + commenter_data = {} + if not self.enable_commenter: + return commenter_data + + db_driver = getattr(self.connect_module, "__name__", "unknown") + db_version = self._get_db_version(db_driver) + + commenter_data = { + "db_driver": f"{db_driver}:{db_version.split(' ')[0]}", + # PEP 249-compliant drivers should have the following attributes. + # We can assume apilevel "1.0" if not given. + # We use "unknown" for others to prevent uncaught AttributeError. + # https://peps.python.org/pep-0249/#globals + "dbapi_threadsafety": getattr( + self.connect_module, "threadsafety", "unknown" + ), + "dbapi_level": getattr(self.connect_module, "apilevel", "1.0"), + "driver_paramstyle": getattr( + self.connect_module, "paramstyle", "unknown" + ), + } + + if self.database_system == "postgresql": + if hasattr(self.connect_module, "__libpq_version__"): + libpq_version = self.connect_module.__libpq_version__ + else: + libpq_version = self.connect_module.pq.__build_version__ + commenter_data.update( + { + "libpq_version": libpq_version, + } + ) + elif self.database_system == "mysql": + mysqlc_version = "" + if db_driver == "MySQLdb": + mysqlc_version = self.connect_module._mysql.get_client_info() + elif db_driver == "pymysql": + mysqlc_version = self.connect_module.get_client_info() + + commenter_data.update( + { + "mysql_client_version": mysqlc_version, + } + ) + + return commenter_data def wrapped_connection( self, @@ -427,21 +496,23 @@ def traced_execution( if args and self._commenter_enabled: try: args_list = list(args) - if hasattr(self._connect_module, "__libpq_version__"): - libpq_version = self._connect_module.__libpq_version__ - else: - libpq_version = ( - self._connect_module.pq.__build_version__ - ) - commenter_data = { - # Psycopg2/framework information - "db_driver": f"psycopg2:{self._connect_module.__version__.split(' ')[0]}", - "dbapi_threadsafety": self._connect_module.threadsafety, - "dbapi_level": self._connect_module.apilevel, - "libpq_version": libpq_version, - "driver_paramstyle": self._connect_module.paramstyle, - } + # lazy capture of mysql-connector client version using cursor + if ( + self._db_api_integration.database_system == "mysql" + and self._db_api_integration.connect_module.__name__ + == "mysql.connector" + and not self._db_api_integration.commenter_data[ + "mysql_client_version" + ] + ): + self._db_api_integration.commenter_data[ + "mysql_client_version" + ] = cursor._cnx._cmysql.get_client_info() + + commenter_data = dict( + self._db_api_integration.commenter_data + ) if self._commenter_options.get( "opentelemetry_values", True ): diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index eb2d628a3a..e29a8ad380 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -24,6 +24,7 @@ from opentelemetry.test.test_base import TestBase +# pylint: disable=too-many-public-methods class TestDBApiIntegration(TestBase): def setUp(self): super().setUp() @@ -252,6 +253,7 @@ def test_executemany(self): def test_executemany_comment(self): connect_module = mock.MagicMock() + connect_module.__name__ = "test" connect_module.__version__ = mock.MagicMock() connect_module.__libpq_version__ = 123 connect_module.apilevel = 123 @@ -260,7 +262,7 @@ def test_executemany_comment(self): db_integration = dbapi.DatabaseApiIntegration( "testname", - "testcomponent", + "postgresql", enable_commenter=True, commenter_options={"db_driver": False, "dbapi_level": False}, connect_module=connect_module, @@ -275,8 +277,38 @@ def test_executemany_comment(self): r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + def test_executemany_comment_non_pep_249_compliant(self): + class MockConnectModule: + def __getattr__(self, name): + if name == "__name__": + return "test" + if name == "__version__": + return mock.MagicMock() + if name == "__libpq_version__": + return 123 + raise AttributeError("attribute missing") + + connect_module = MockConnectModule() + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + connect_module=connect_module, + commenter_options={"db_driver": False}, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_level='1.0',dbapi_threadsafety='unknown',driver_paramstyle='unknown',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + def test_compatible_build_version_psycopg_psycopg2_libpq(self): connect_module = mock.MagicMock() + connect_module.__name__ = "test" connect_module.__version__ = mock.MagicMock() connect_module.pq = mock.MagicMock() connect_module.pq.__build_version__ = 123 @@ -286,7 +318,7 @@ def test_compatible_build_version_psycopg_psycopg2_libpq(self): db_integration = dbapi.DatabaseApiIntegration( "testname", - "testcomponent", + "postgresql", enable_commenter=True, commenter_options={"db_driver": False, "dbapi_level": False}, connect_module=connect_module, @@ -301,8 +333,150 @@ def test_compatible_build_version_psycopg_psycopg2_libpq(self): r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + def test_executemany_psycopg2_integration_comment(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "psycopg2" + connect_module.__version__ = "1.2.3" + connect_module.__libpq_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='psycopg2%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + + def test_executemany_psycopg_integration_comment(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "psycopg" + connect_module.__version__ = "1.2.3" + connect_module.pq = mock.MagicMock() + connect_module.pq.__build_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='psycopg%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + + def test_executemany_mysqlconnector_integration_comment(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "mysql.connector" + connect_module.__version__ = "1.2.3" + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "mysql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + ) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='mysql.connector%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='1.2.3',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + + @mock.patch("opentelemetry.instrumentation.dbapi.util_version") + def test_executemany_mysqlclient_integration_comment( + self, + mock_dbapi_util_version, + ): + mock_dbapi_util_version.return_value = "1.2.3" + connect_module = mock.MagicMock() + connect_module.__name__ = "MySQLdb" + connect_module.__version__ = "1.2.3" + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + connect_module._mysql = mock.MagicMock() + connect_module._mysql.get_client_info = mock.MagicMock( + return_value="123" + ) + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "mysql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + ) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='MySQLdb%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + + def test_executemany_pymysql_integration_comment(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "pymysql" + connect_module.__version__ = "1.2.3" + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + connect_module.get_client_info = mock.MagicMock(return_value="123") + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "mysql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + ) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='pymysql%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + def test_executemany_flask_integration_comment(self): connect_module = mock.MagicMock() + connect_module.__name__ = "test" connect_module.__version__ = mock.MagicMock() connect_module.__libpq_version__ = 123 connect_module.apilevel = 123 @@ -311,7 +485,7 @@ def test_executemany_flask_integration_comment(self): db_integration = dbapi.DatabaseApiIntegration( "testname", - "testcomponent", + "postgresql", enable_commenter=True, commenter_options={"db_driver": False, "dbapi_level": False}, connect_module=connect_module, @@ -332,6 +506,11 @@ def test_executemany_flask_integration_comment(self): r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',flask=1,libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + clear_context = context.set_value( + "SQLCOMMENTER_ORM_TAGS_AND_VALUES", {}, current_context + ) + context.attach(clear_context) + def test_callproc(self): db_integration = dbapi.DatabaseApiIntegration( "testname", "testcomponent" @@ -415,6 +594,12 @@ class MockCursor: def __init__(self) -> None: self.query = "" self.params = None + # Mock mysql.connector modules and method + self._cnx = mock.MagicMock() + self._cnx._cmysql = mock.MagicMock() + self._cnx._cmysql.get_client_info = mock.MagicMock( + return_value="1.2.3" + ) # pylint: disable=unused-argument, no-self-use def execute(self, query, params=None, throw_exception=False): From 54c7ee80abc9c6edefa52169ba8904deaf7e7491 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 30 Oct 2024 19:43:33 +0100 Subject: [PATCH 209/335] exporter/prometheus_remote_write: sort labels before exporting (#2940) --- CHANGELOG.md | 2 ++ .../prometheus_remote_write/__init__.py | 8 +++-- .../test_prometheus_remote_write_exporter.py | 34 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29a34bae1f..47191002dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2922](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2922)) - `opentelemetry-instrumentation-celery` Don't detach context without a None token ([#2927](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2927)) +- `opentelemetry-exporter-prometheus-remote-write`: sort labels before exporting + ([#2940](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2940)) - `opentelemetry-instrumentation-dbapi` sqlcommenter key values created from PostgreSQL, MySQL systems ([#2897](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2897)) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py index 78b8516a46..cfb1d9ea75 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/__init__.py @@ -16,7 +16,7 @@ import re from collections import defaultdict from itertools import chain -from typing import Dict, Sequence +from typing import Dict, Mapping, Sequence import requests import snappy @@ -253,12 +253,14 @@ def _parse_metric( return self._convert_to_timeseries(sample_sets, resource_labels) def _convert_to_timeseries( - self, sample_sets: Sequence[tuple], resource_labels: Sequence + self, sample_sets: Mapping[tuple, Sequence], resource_labels: Sequence ) -> Sequence[TimeSeries]: timeseries = [] for labels, samples in sample_sets.items(): ts = TimeSeries() - for label_name, label_value in chain(resource_labels, labels): + for label_name, label_value in sorted( + chain(resource_labels, labels) + ): # Previous implementation did not str() the names... ts.labels.append(self._label(label_name, str(label_value))) for value, timestamp in samples: diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/tests/test_prometheus_remote_write_exporter.py b/exporter/opentelemetry-exporter-prometheus-remote-write/tests/test_prometheus_remote_write_exporter.py index 785c6bdc29..1c50344353 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/tests/test_prometheus_remote_write_exporter.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/tests/test_prometheus_remote_write_exporter.py @@ -22,6 +22,8 @@ PrometheusRemoteWriteMetricsExporter, ) from opentelemetry.exporter.prometheus_remote_write.gen.types_pb2 import ( # pylint: disable=E0611 + Label, + Sample, TimeSeries, ) from opentelemetry.sdk.metrics.export import ( @@ -155,6 +157,38 @@ def test_parse_metric(metric, prom_rw): assert sample.value in values +def test_convert_to_timeseries(prom_rw): + resource_labels = (("service_name", "foo"), ("bool_value", True)) + sample_sets = { + (("foo", "bar"), ("baz", 42), ("__name__", "test_histogram_tu")): [ + (1, 1641946016139) + ], + (("baz", "42"), ("foo", "bar")): [(4, 1641946016139)], + } + timeseries = prom_rw._convert_to_timeseries(sample_sets, resource_labels) + assert timeseries == [ + TimeSeries( + labels=[ + Label(name="__name__", value="test_histogram_tu"), + Label(name="baz", value="42"), + Label(name="bool_value", value="True"), + Label(name="foo", value="bar"), + Label(name="service_name", value="foo"), + ], + samples=[Sample(value=1, timestamp=1641946016139)], + ), + TimeSeries( + labels=[ + Label(name="baz", value="42"), + Label(name="bool_value", value="True"), + Label(name="foo", value="bar"), + Label(name="service_name", value="foo"), + ], + samples=[Sample(value=4, timestamp=1641946016139)], + ), + ] + + class TestValidation(unittest.TestCase): # Test cases to ensure exporter parameter validation works as intended def test_valid_standard_param(self): From 07c3324a3bcf80ee716f90b2456f59af08b685fa Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 30 Oct 2024 14:07:24 -0700 Subject: [PATCH 210/335] OpenAI - update semantic conventions to the latest version, write logs based events instead of span events (#2925) --- .../CHANGELOG.md | 15 + .../README.rst | 4 +- .../instrumentation/openai_v2/__init__.py | 20 +- .../instrumentation/openai_v2/patch.py | 313 ++++--- .../instrumentation/openai_v2/utils.py | 218 +++-- .../test-requirements.txt | 2 +- .../cassettes/test_chat_completion_404.yaml | 75 ++ .../test_chat_completion_extra_params.yaml | 99 ++ ...test_chat_completion_multiple_choices.yaml | 100 ++ ...completion_multiple_choices_streaming.yaml | 491 ++++++++++ ...n_multiple_tools_streaming_no_content.yaml | 155 ++++ ...multiple_tools_streaming_with_content.yaml | 155 ++++ ...hat_completion_streaming_not_complete.yaml | 117 +++ ...chat_completion_tool_calls_no_content.yaml | 215 +++++ ...at_completion_tool_calls_with_content.yaml | 215 +++++ ...=> test_chat_completion_with_content.yaml} | 0 .../tests/conftest.py | 73 +- .../tests/test_chat_completions.py | 874 ++++++++++++++++-- tox.ini | 3 + 19 files changed, 2813 insertions(+), 331 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/CHANGELOG.md create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml rename instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/{test_chat_completion.yaml => test_chat_completion_with_content.yaml} (100%) diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation/opentelemetry-instrumentation-openai-v2/CHANGELOG.md new file mode 100644 index 0000000000..3509eb5b79 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +- Update OpenAI instrumentation to Semantic Conventions v1.28.0: add new attributes + and switch prompts and completions to log-based events. + ([#2925](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2925)) + +- Initial OpenAI instrumentation + ([#2759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2759)) \ No newline at end of file diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst index cd7e9b3922..85817896ff 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst @@ -1,12 +1,12 @@ OpenTelemetry OpenAI Instrumentation -==================================== +==================================== |pypi| .. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-openai-v2.svg :target: https://pypi.org/project/opentelemetry-instrumentation-openai-v2/ -Instrumentation with OpenAI that supports the openai library and is +Instrumentation with OpenAI that supports the OpenAI library and is specified to trace_integration using 'OpenAI'. diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py index 347ddb70ff..e8a782e404 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -24,7 +24,7 @@ .. code:: python from openai import OpenAI - from opentelemetry.instrumentation.openai import OpenAIInstrumentor + from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor OpenAIInstrumentor().instrument() @@ -44,8 +44,10 @@ from wrapt import wrap_function_wrapper +from opentelemetry._events import get_event_logger from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.openai_v2.package import _instruments +from opentelemetry.instrumentation.openai_v2.utils import is_content_enabled from opentelemetry.instrumentation.utils import unwrap from opentelemetry.semconv.schemas import Schemas from opentelemetry.trace import get_tracer @@ -64,15 +66,25 @@ def _instrument(self, **kwargs): __name__, "", tracer_provider, - schema_url=Schemas.V1_27_0.value, + schema_url=Schemas.V1_28_0.value, ) + event_logger_provider = kwargs.get("event_logger_provider") + event_logger = get_event_logger( + __name__, + "", + schema_url=Schemas.V1_28_0.value, + event_logger_provider=event_logger_provider, + ) + wrap_function_wrapper( module="openai.resources.chat.completions", name="Completions.create", - wrapper=chat_completions_create(tracer), + wrapper=chat_completions_create( + tracer, event_logger, is_content_enabled() + ), ) def _uninstrument(self, **kwargs): - import openai + import openai # pylint: disable=import-outside-toplevel unwrap(openai.resources.chat.completions.Completions, "create") diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index ddc54cad19..8540bff219 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -13,8 +13,11 @@ # limitations under the License. -import json +from typing import Optional +from openai import Stream + +from opentelemetry._events import Event, EventLogger from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) @@ -25,97 +28,73 @@ from opentelemetry.trace.status import Status, StatusCode from .utils import ( - extract_content, - extract_tools_prompt, + choice_to_event, get_llm_request_attributes, is_streaming, - set_event_completion, - set_event_prompt, + message_to_event, set_span_attribute, - silently_fail, ) -def chat_completions_create(tracer: Tracer): +def chat_completions_create( + tracer: Tracer, event_logger: EventLogger, capture_content: bool +): """Wrap the `create` method of the `ChatCompletion` class to trace it.""" def traced_method(wrapped, instance, args, kwargs): - llm_prompts = [] - - for item in kwargs.get("messages", []): - tools_prompt = extract_tools_prompt(item) - llm_prompts.append(tools_prompt if tools_prompt else item) + span_attributes = {**get_llm_request_attributes(kwargs, instance)} - span_attributes = {**get_llm_request_attributes(kwargs)} span_name = f"{span_attributes[GenAIAttributes.GEN_AI_OPERATION_NAME]} {span_attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL]}" + with tracer.start_as_current_span( + name=span_name, + kind=SpanKind.CLIENT, + attributes=span_attributes, + end_on_exit=False, + ) as span: + if span.is_recording(): + for message in kwargs.get("messages", []): + event_logger.emit( + message_to_event(message, capture_content) + ) + + try: + result = wrapped(*args, **kwargs) + if is_streaming(kwargs): + return StreamWrapper( + result, span, event_logger, capture_content + ) - span = tracer.start_span( - name=span_name, kind=SpanKind.CLIENT, attributes=span_attributes - ) - if span.is_recording(): - _set_input_attributes(span, span_attributes) - set_event_prompt(span, json.dumps(llm_prompts)) - - try: - result = wrapped(*args, **kwargs) - if is_streaming(kwargs): - return StreamWrapper( - result, - span, - function_call=kwargs.get("functions") is not None, - tool_calls=kwargs.get("tools") is not None, - ) - else: if span.is_recording(): - _set_response_attributes(span, result) + _set_response_attributes( + span, result, event_logger, capture_content + ) span.end() return result - except Exception as error: - span.set_status(Status(StatusCode.ERROR, str(error))) - if span.is_recording(): - span.set_attribute( - ErrorAttributes.ERROR_TYPE, type(error).__qualname__ - ) - span.end() - raise + except Exception as error: + span.set_status(Status(StatusCode.ERROR, str(error))) + if span.is_recording(): + span.set_attribute( + ErrorAttributes.ERROR_TYPE, type(error).__qualname__ + ) + span.end() + raise return traced_method -@silently_fail -def _set_input_attributes(span, attributes): - for field, value in attributes.items(): - set_span_attribute(span, field, value) - - -@silently_fail -def _set_response_attributes(span, result): +def _set_response_attributes( + span, result, event_logger: EventLogger, capture_content: bool +): set_span_attribute( span, GenAIAttributes.GEN_AI_RESPONSE_MODEL, result.model ) + if getattr(result, "choices", None): choices = result.choices - responses = [ - { - "role": ( - choice.message.role - if choice.message and choice.message.role - else "assistant" - ), - "content": extract_content(choice), - **( - { - "content_filter_results": choice[ - "content_filter_results" - ] - } - if "content_filter_results" in choice - else {} - ), - } - for choice in choices - ] + for choice in choices: + event_logger.emit(choice_to_event(choice, capture_content)) + finish_reasons = [] for choice in choices: finish_reasons.append(choice.finish_reason or "error") @@ -125,11 +104,17 @@ def _set_response_attributes(span, result): GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, finish_reasons, ) - set_event_completion(span, responses) if getattr(result, "id", None): set_span_attribute(span, GenAIAttributes.GEN_AI_RESPONSE_ID, result.id) + if getattr(result, "service_tier", None): + set_span_attribute( + span, + GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER, + result.service_tier, + ) + # Get the usage if getattr(result, "usage", None): set_span_attribute( @@ -144,27 +129,65 @@ def _set_response_attributes(span, result): ) +class ToolCallBuffer: + def __init__(self, index, tool_call_id, function_name): + self.index = index + self.function_name = function_name + self.tool_call_id = tool_call_id + self.arguments = [] + + def append_arguments(self, arguments): + self.arguments.append(arguments) + + +class ChoiceBuffer: + def __init__(self, index): + self.index = index + self.finish_reason = None + self.text_content = [] + self.tool_calls_buffers = [] + + def append_text_content(self, content): + self.text_content.append(content) + + def append_tool_call(self, tool_call): + idx = tool_call.index + # make sure we have enough tool call buffers + for _ in range(len(self.tool_calls_buffers), idx + 1): + self.tool_calls_buffers.append(None) + + if not self.tool_calls_buffers[idx]: + self.tool_calls_buffers[idx] = ToolCallBuffer( + idx, tool_call.id, tool_call.function.name + ) + self.tool_calls_buffers[idx].append_arguments( + tool_call.function.arguments + ) + + class StreamWrapper: span: Span - response_id: str = "" - response_model: str = "" + response_id: Optional[str] = None + response_model: Optional[str] = None + service_tier: Optional[str] = None + finish_reasons: list = [] + prompt_tokens: Optional[int] = 0 + completion_tokens: Optional[int] = 0 def __init__( self, - stream, - span, - prompt_tokens=0, - function_call=False, - tool_calls=False, + stream: Stream, + span: Span, + event_logger: EventLogger, + capture_content: bool, ): self.stream = stream self.span = span - self.prompt_tokens = prompt_tokens - self.function_call = function_call - self.tool_calls = tool_calls - self.result_content = [] - self.completion_tokens = 0 + self.choice_buffers = [] self._span_started = False + self.capture_content = capture_content + + self.event_logger = event_logger self.setup() def setup(self): @@ -197,16 +220,62 @@ def cleanup(self): GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, self.completion_tokens, ) - set_event_completion( + + set_span_attribute( + self.span, + GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER, + self.service_tier, + ) + + set_span_attribute( self.span, - [ - { - "role": "assistant", - "content": "".join(self.result_content), - } - ], + GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, + self.finish_reasons, ) + for idx, choice in enumerate(self.choice_buffers): + message = {"role": "assistant"} + if self.capture_content and choice.text_content: + message["content"] = "".join(choice.text_content) + if choice.tool_calls_buffers: + tool_calls = [] + for tool_call in choice.tool_calls_buffers: + function = {"name": tool_call.function_name} + if self.capture_content: + function["arguments"] = "".join( + tool_call.arguments + ) + tool_call_dict = { + "id": tool_call.tool_call_id, + "type": "function", + "function": function, + } + tool_calls.append(tool_call_dict) + message["tool_calls"] = tool_calls + + body = { + "index": idx, + "finish_reason": choice.finish_reason or "error", + "message": message, + } + + event_attributes = { + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value + } + + # this span is not current, so we need to manually set the context on event + span_ctx = self.span.get_span_context() + self.event_logger.emit( + Event( + name="gen_ai.choice", + attributes=event_attributes, + body=body, + trace_id=span_ctx.trace_id, + span_id=span_ctx.span_id, + trace_flags=span_ctx.trace_flags, + ) + ) + self.span.end() self._span_started = False @@ -225,6 +294,10 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.cleanup() return False # Propagate the exception + def close(self): + self.stream.close() + self.cleanup() + def __iter__(self): return self @@ -258,50 +331,41 @@ def set_response_id(self, chunk): if getattr(chunk, "id", None): self.response_id = chunk.id + def set_response_service_tier(self, chunk): + if self.service_tier: + return + + if getattr(chunk, "service_tier", None): + self.service_tier = chunk.service_tier + def build_streaming_response(self, chunk): if getattr(chunk, "choices", None) is None: return choices = chunk.choices - content = [] - if not self.function_call and not self.tool_calls: - for choice in choices: - if choice.delta and choice.delta.content is not None: - content = [choice.delta.content] - - elif self.function_call: - for choice in choices: - if ( - choice.delta - and choice.delta.function_call is not None - and choice.delta.function_call.arguments is not None - ): - content = [choice.delta.function_call.arguments] - - elif self.tool_calls: - for choice in choices: - if choice.delta and choice.delta.tool_calls is not None: - toolcalls = choice.delta.tool_calls - content = [] - for tool_call in toolcalls: - if ( - tool_call - and tool_call.function is not None - and tool_call.function.arguments is not None - ): - content.append(tool_call.function.arguments) - - finish_reasons = [] for choice in choices: - finish_reasons.append(choice.finish_reason or "error") + if not choice.delta: + continue - set_span_attribute( - self.span, - GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, - finish_reasons, - ) - if content: - self.result_content.append(content[0]) + # make sure we have enough choice buffers + for idx in range(len(self.choice_buffers), choice.index + 1): + self.choice_buffers.append(ChoiceBuffer(idx)) + + if choice.finish_reason: + self.choice_buffers[ + choice.index + ].finish_reason = choice.finish_reason + + if choice.delta.content is not None: + self.choice_buffers[choice.index].append_text_content( + choice.delta.content + ) + + if choice.delta.tool_calls is not None: + for tool_call in choice.delta.tool_calls: + self.choice_buffers[choice.index].append_tool_call( + tool_call + ) def set_usage(self, chunk): if getattr(chunk, "usage", None): @@ -311,5 +375,6 @@ def set_usage(self, chunk): def process_chunk(self, chunk): self.set_response_id(chunk) self.set_response_model(chunk) + self.set_response_service_tier(chunk) self.build_streaming_response(chunk) self.set_usage(chunk) diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index ba2301cc5d..ffbf3db5aa 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -12,117 +12,156 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json -import logging +from os import environ from typing import Optional, Union +from urllib.parse import urlparse +from httpx import URL from openai import NOT_GIVEN +from opentelemetry._events import Event from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) +OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT = ( + "OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT" +) -def silently_fail(func): - """ - A decorator that catches exceptions thrown by the decorated function and logs them as warnings. - """ - - logger = logging.getLogger(func.__module__) - - def wrapper(*args, **kwargs): - try: - return func(*args, **kwargs) - except Exception as exception: - logger.warning( - "Failed to execute %s, error: %s", - func.__name__, - str(exception), - ) - - return wrapper - - -def extract_content(choice): - if getattr(choice, "message", None) is None: - return "" - - # Check if choice.message exists and has a content attribute - message = choice.message - if getattr(message, "content", None): - return choice.message.content - - # Check if choice.message has tool_calls and extract information accordingly - elif getattr(message, "tool_calls", None): - result = [ - { - "id": tool_call.id, - "type": tool_call.type, - "function": { - "name": tool_call.function.name, - "arguments": tool_call.function.arguments, - }, - } - for tool_call in choice.message.tool_calls - ] - return result - - # Check if choice.message has a function_call and extract information accordingly - elif getattr(message, "function_call", None): - return { - "name": choice.message.function_call.name, - "arguments": choice.message.function_call.arguments, - } - # Return an empty string if none of the above conditions are met - else: - return "" +def is_content_enabled() -> bool: + capture_content = environ.get( + OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT, "false" + ) + + return capture_content.lower() == "true" -def extract_tools_prompt(item): - tool_calls = getattr(item, "tool_calls", None) +def extract_tool_calls(item, capture_content): + tool_calls = get_property_value(item, "tool_calls") if tool_calls is None: - return + return None calls = [] for tool_call in tool_calls: - tool_call_dict = { - "id": getattr(tool_call, "id", ""), - "type": getattr(tool_call, "type", ""), - } + tool_call_dict = {} + call_id = get_property_value(tool_call, "id") + if call_id: + tool_call_dict["id"] = call_id + + tool_type = get_property_value(tool_call, "type") + if tool_type: + tool_call_dict["type"] = tool_type + + func = get_property_value(tool_call, "function") + if func: + tool_call_dict["function"] = {} + + name = get_property_value(func, "name") + if name: + tool_call_dict["function"]["name"] = name + + arguments = get_property_value(func, "arguments") + if capture_content and arguments: + if isinstance(arguments, str): + arguments = arguments.replace("\n", "") + tool_call_dict["function"]["arguments"] = arguments - if hasattr(tool_call, "function"): - tool_call_dict["function"] = { - "name": getattr(tool_call.function, "name", ""), - "arguments": getattr(tool_call.function, "arguments", ""), - } calls.append(tool_call_dict) return calls -def set_event_prompt(span, prompt): - span.add_event( - name="gen_ai.content.prompt", - attributes={ - GenAIAttributes.GEN_AI_PROMPT: prompt, - }, +def set_server_address_and_port(client_instance, attributes): + base_client = getattr(client_instance, "_client", None) + base_url = getattr(base_client, "base_url", None) + if not base_url: + return + + port = -1 + if isinstance(base_url, URL): + attributes[ServerAttributes.SERVER_ADDRESS] = base_url.host + port = base_url.port + elif isinstance(base_url, str): + url = urlparse(base_url) + attributes[ServerAttributes.SERVER_ADDRESS] = url.hostname + port = url.port + + if port and port != 443 and port > 0: + attributes[ServerAttributes.SERVER_PORT] = port + + +def get_property_value(obj, property_name): + if isinstance(obj, dict): + return obj.get(property_name, None) + + return getattr(obj, property_name, None) + + +def message_to_event(message, capture_content): + attributes = { + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value + } + role = get_property_value(message, "role") + content = get_property_value(message, "content") + + body = {} + if capture_content and content: + body["content"] = content + if role == "assistant": + tool_calls = extract_tool_calls(message, capture_content) + if tool_calls: + body = {"tool_calls": tool_calls} + elif role == "tool": + tool_call_id = get_property_value(message, "tool_call_id") + if tool_call_id: + body["id"] = tool_call_id + + return Event( + name=f"gen_ai.{role}.message", + attributes=attributes, + body=body if body else None, ) -def set_span_attributes(span, attributes: dict): - for field, value in attributes.model_dump(by_alias=True).items(): - set_span_attribute(span, field, value) +def choice_to_event(choice, capture_content): + attributes = { + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value + } + body = { + "index": choice.index, + "finish_reason": choice.finish_reason or "error", + } -def set_event_completion(span, result_content): - span.add_event( - name="gen_ai.content.completion", - attributes={ - GenAIAttributes.GEN_AI_COMPLETION: json.dumps(result_content), - }, + if choice.message: + message = { + "role": choice.message.role + if choice.message and choice.message.role + else None + } + tool_calls = extract_tool_calls(choice.message, capture_content) + if tool_calls: + message["tool_calls"] = tool_calls + content = get_property_value(choice.message, "content") + if capture_content and content: + message["content"] = content + body["message"] = message + + return Event( + name="gen_ai.choice", + attributes=attributes, + body=body, ) +def set_span_attributes(span, attributes: dict): + for field, value in attributes.model_dump(by_alias=True).items(): + set_span_attribute(span, field, value) + + def set_span_attribute(span, name, value): if non_numerical_value_is_set(value) is False: return @@ -140,14 +179,13 @@ def non_numerical_value_is_set(value: Optional[Union[bool, str]]): def get_llm_request_attributes( kwargs, + client_instance, operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value, ): attributes = { GenAIAttributes.GEN_AI_OPERATION_NAME: operation_name, GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value, - GenAIAttributes.GEN_AI_REQUEST_MODEL: kwargs.get( - "model", "gpt-3.5-turbo" - ), + GenAIAttributes.GEN_AI_REQUEST_MODEL: kwargs.get("model"), GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: kwargs.get("temperature"), GenAIAttributes.GEN_AI_REQUEST_TOP_P: kwargs.get("p") or kwargs.get("top_p"), @@ -158,7 +196,17 @@ def get_llm_request_attributes( GenAIAttributes.GEN_AI_REQUEST_FREQUENCY_PENALTY: kwargs.get( "frequency_penalty" ), + GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: kwargs.get( + "response_format" + ), + GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED: kwargs.get("seed"), } + set_server_address_and_port(client_instance, attributes) + service_tier = kwargs.get("service_tier") + attributes[GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER] = ( + service_tier if service_tier != "auto" else None + ) + # filter out None values return {k: v for k, v in attributes.items() if v is not None} diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt index 198226dcfa..a3d7402a9c 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt @@ -1,4 +1,4 @@ -openai==1.26.0 +openai==1.26.0 pydantic==2.8.2 Deprecated==1.2.14 importlib-metadata==6.11.0 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml new file mode 100644 index 0000000000..1b7a7988ca --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml @@ -0,0 +1,75 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": + "this-model-does-not-exist"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '103' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '2' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"error\": {\n \"message\": \"The model `this-model-does-not-exist` + does not exist or you do not have access to it.\",\n \"type\": \"invalid_request_error\",\n + \ \"param\": null,\n \"code\": \"model_not_found\"\n }\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d88b04c2c5db9eb-SEA + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Sat, 26 Oct 2024 07:21:17 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '231' + openai-organization: test_organization + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Origin + x-request-id: + - req_8529656422f0360e8bcba8c2b8fe34e9 + status: + code: 404 + message: Not Found +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml new file mode 100644 index 0000000000..75903a6a55 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml @@ -0,0 +1,99 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": + "gpt-4o-mini", "max_tokens": 50, "seed": 42, "service_tier": "auto", "stream": + false, "temperature": 0.5}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '180' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AMTlCEj20ZcsgWKZt8EizFMDItWNf\",\n \"object\": + \"chat.completion\",\n \"created\": 1729920978,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"This is a test. How can I assist you + further?\",\n \"refusal\": null\n },\n \"logprobs\": null,\n + \ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": + 12,\n \"completion_tokens\": 12,\n \"total_tokens\": 24,\n \"prompt_tokens_details\": + {\n \"cached_tokens\": 0\n },\n \"completion_tokens_details\": + {\n \"reasoning_tokens\": 0\n }\n },\n \"service_tier\": \"default\",\n + \ \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d881682197c7571-SEA + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Sat, 26 Oct 2024 05:36:18 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '697' + openai-organization: test_organization + openai-processing-ms: + - '275' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '195' + x-ratelimit-remaining-tokens: + - '59944' + x-ratelimit-reset-requests: + - 32m17.492s + x-ratelimit-reset-tokens: + - 56ms + x-request-id: + - req_181075e8f861d6685fe1ae5d4bfc9b25 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml new file mode 100644 index 0000000000..2416a06cb8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml @@ -0,0 +1,100 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": + "gpt-4o-mini", "n": 2, "stream": false}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '114' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AMT4dWD9gi2PyDcXBK10harskeREO\",\n \"object\": + \"chat.completion\",\n \"created\": 1729918339,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"This is a test.\",\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n + \ },\n {\n \"index\": 1,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"This is a test. How can I assist you + further?\",\n \"refusal\": null\n },\n \"logprobs\": null,\n + \ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": + 12,\n \"completion_tokens\": 17,\n \"total_tokens\": 29,\n \"prompt_tokens_details\": + {\n \"cached_tokens\": 0\n },\n \"completion_tokens_details\": + {\n \"reasoning_tokens\": 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d87d6120a899357-SEA + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Sat, 26 Oct 2024 04:52:19 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '872' + openai-organization: test_organization + openai-processing-ms: + - '664' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '199' + x-ratelimit-remaining-tokens: + - '59962' + x-ratelimit-reset-requests: + - 7m12s + x-ratelimit-reset-tokens: + - 38ms + x-request-id: + - req_d8b7a2507994f22fe0d4511c7e0a3bdc + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml new file mode 100644 index 0000000000..c5be0fa9d4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml @@ -0,0 +1,491 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}], "model": "gpt-4o-mini", "n": 2, "stream": true, "stream_options": + {"include_usage": true}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '254' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: 'data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"I''m"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"I''m"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + sorry"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + to"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + but"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + real"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + I"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + can''t"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + real"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + However"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + you"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + as"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + can"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + my"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + easily"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + training"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + check"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + data"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + the"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + goes"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + current"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + up"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + in"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + to"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + October"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + "},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + and"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + San"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + and"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + using"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + I"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + websites"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + like"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + the"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + don''t"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + have"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + access"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + to"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + Weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + live"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + Channel"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + data"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + Acc"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"u"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"Weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + I"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + recommend"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + checking"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + a"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + reliable"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + website"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + or"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + using"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + a"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + or"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + a"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + app"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + on"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + your"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" + smartphone"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + app"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + for"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + the"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + most"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + current"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + information"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + on"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + the"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + in"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + and"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + San"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" + Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + + data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":100,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + + + data: [DONE] + + + ' + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d883e57eb7227f9-SEA + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Sat, 26 Oct 2024 06:03:30 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_organization + openai-processing-ms: + - '216' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '194' + x-ratelimit-remaining-tokens: + - '59945' + x-ratelimit-reset-requests: + - 41m5.83s + x-ratelimit-reset-tokens: + - 55ms + x-request-id: + - req_2cafe46d3edfcc0f61e4885c27cca46e + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml new file mode 100644 index 0000000000..86085d12cf --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml @@ -0,0 +1,155 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "stream": true, + "stream_options": {"include_usage": true}, "tool_choice": "auto", "tools": [{"type": + "function", "function": {"name": "get_current_weather", "description": "Get + the current weather in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. Boston, + MA"}}, "required": ["location"], "additionalProperties": false}}}]}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '631' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: 'data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_yy3bBunEUS0C3HGZECG9EGCj","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": + \"S"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, + W"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ug3IE7qMdaP4tBJwJHacc7GO","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": + \"S"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an + F"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, + C"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + + + data: [DONE] + + + ' + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d887ec3b9047639-SEA + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Sat, 26 Oct 2024 06:47:29 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_organization + openai-processing-ms: + - '723' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '197' + x-ratelimit-remaining-tokens: + - '59961' + x-ratelimit-reset-requests: + - 18m43.156s + x-ratelimit-reset-tokens: + - 39ms + x-request-id: + - req_81b3cd6dbe38ffddcdca90c699f71f84 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml new file mode 100644 index 0000000000..86085d12cf --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml @@ -0,0 +1,155 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "stream": true, + "stream_options": {"include_usage": true}, "tool_choice": "auto", "tools": [{"type": + "function", "function": {"name": "get_current_weather", "description": "Get + the current weather in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. Boston, + MA"}}, "required": ["location"], "additionalProperties": false}}}]}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '631' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: 'data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_yy3bBunEUS0C3HGZECG9EGCj","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": + \"S"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, + W"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ug3IE7qMdaP4tBJwJHacc7GO","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": + \"S"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an + F"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, + C"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + + data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + + + data: [DONE] + + + ' + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d887ec3b9047639-SEA + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Sat, 26 Oct 2024 06:47:29 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_organization + openai-processing-ms: + - '723' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '197' + x-ratelimit-remaining-tokens: + - '59961' + x-ratelimit-reset-requests: + - 18m43.156s + x-ratelimit-reset-tokens: + - 39ms + x-request-id: + - req_81b3cd6dbe38ffddcdca90c699f71f84 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml new file mode 100644 index 0000000000..ea683057c3 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml @@ -0,0 +1,117 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": + "gpt-4", "stream": true, "stream_options": {"include_usage": true}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '142' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: 'data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" + is"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" + a"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" + test"},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + + data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + + + data: [DONE] + + + ' + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d88bd2c0d9e308c-SEA + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Sat, 26 Oct 2024 07:30:05 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_organization + openai-processing-ms: + - '176' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '10000' + x-ratelimit-remaining-requests: + - '199' + x-ratelimit-remaining-tokens: + - '9978' + x-ratelimit-reset-requests: + - 7m12s + x-ratelimit-reset-tokens: + - 132ms + x-request-id: + - req_6ff271d00318adcd2408d8dcd5f93ec7 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml new file mode 100644 index 0000000000..9a8b489489 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml @@ -0,0 +1,215 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "tool_choice": + "auto", "tools": [{"type": "function", "function": {"name": "get_current_weather", + "description": "Get the current weather in a given location", "parameters": + {"type": "object", "properties": {"location": {"type": "string", "description": + "The city and state, e.g. Boston, MA"}}, "required": ["location"], "additionalProperties": + false}}}]}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '572' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AMTFkpz8qllCCkh1A8xzoe14DwAQN\",\n \"object\": + \"chat.completion\",\n \"created\": 1729919028,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": null,\n \"tool_calls\": [\n {\n + \ \"id\": \"call_YBUn0S5ErhjkfnjFbWWJYIvR\",\n \"type\": + \"function\",\n \"function\": {\n \"name\": \"get_current_weather\",\n + \ \"arguments\": \"{\\\"location\\\": \\\"Seattle, WA\\\"}\"\n + \ }\n },\n {\n \"id\": \"call_Ail5xuGFVRk2wUPidQWDYytn\",\n + \ \"type\": \"function\",\n \"function\": {\n \"name\": + \"get_current_weather\",\n \"arguments\": \"{\\\"location\\\": + \\\"San Francisco, CA\\\"}\"\n }\n }\n ],\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"tool_calls\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 75,\n \"completion_tokens\": + 51,\n \"total_tokens\": 126,\n \"prompt_tokens_details\": {\n \"cached_tokens\": + 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d87e6e7ba75dee2-SEA + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Sat, 26 Oct 2024 05:03:49 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1180' + openai-organization: test_organization + openai-processing-ms: + - '649' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '198' + x-ratelimit-remaining-tokens: + - '59961' + x-ratelimit-reset-requests: + - 14m23.304s + x-ratelimit-reset-tokens: + - 39ms + x-request-id: + - req_b2f085c19f19c32c8aa891887e228402 + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}, {"role": "assistant", "tool_calls": [{"id": "call_YBUn0S5ErhjkfnjFbWWJYIvR", + "function": {"arguments": "{\"location\": \"Seattle, WA\"}", "name": "get_current_weather"}, + "type": "function"}, {"id": "call_Ail5xuGFVRk2wUPidQWDYytn", "function": {"arguments": + "{\"location\": \"San Francisco, CA\"}", "name": "get_current_weather"}, "type": + "function"}]}, {"role": "tool", "content": "50 degrees and raining", "tool_call_id": + "call_YBUn0S5ErhjkfnjFbWWJYIvR"}, {"role": "tool", "content": "70 degrees and + sunny", "tool_call_id": "call_Ail5xuGFVRk2wUPidQWDYytn"}], "model": "gpt-4o-mini"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_set_cookie + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AMTFlFwfqawbaH57GE3mXL8O17xo1\",\n \"object\": + \"chat.completion\",\n \"created\": 1729919029,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"Today, the weather in Seattle is 50 + degrees and raining, while in San Francisco, it is 70 degrees and sunny.\",\n + \ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": + \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 99,\n \"completion_tokens\": + 26,\n \"total_tokens\": 125,\n \"prompt_tokens_details\": {\n \"cached_tokens\": + 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d87e6ec8ddedee2-SEA + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Sat, 26 Oct 2024 05:03:49 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '732' + openai-organization: test_organization + openai-processing-ms: + - '537' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '197' + x-ratelimit-remaining-tokens: + - '59948' + x-ratelimit-reset-requests: + - 21m34.534s + x-ratelimit-reset-tokens: + - 52ms + x-request-id: + - req_ca78782b171f5cd60841ba443de92731 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml new file mode 100644 index 0000000000..9a8b489489 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml @@ -0,0 +1,215 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "tool_choice": + "auto", "tools": [{"type": "function", "function": {"name": "get_current_weather", + "description": "Get the current weather in a given location", "parameters": + {"type": "object", "properties": {"location": {"type": "string", "description": + "The city and state, e.g. Boston, MA"}}, "required": ["location"], "additionalProperties": + false}}}]}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '572' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AMTFkpz8qllCCkh1A8xzoe14DwAQN\",\n \"object\": + \"chat.completion\",\n \"created\": 1729919028,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": null,\n \"tool_calls\": [\n {\n + \ \"id\": \"call_YBUn0S5ErhjkfnjFbWWJYIvR\",\n \"type\": + \"function\",\n \"function\": {\n \"name\": \"get_current_weather\",\n + \ \"arguments\": \"{\\\"location\\\": \\\"Seattle, WA\\\"}\"\n + \ }\n },\n {\n \"id\": \"call_Ail5xuGFVRk2wUPidQWDYytn\",\n + \ \"type\": \"function\",\n \"function\": {\n \"name\": + \"get_current_weather\",\n \"arguments\": \"{\\\"location\\\": + \\\"San Francisco, CA\\\"}\"\n }\n }\n ],\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"tool_calls\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 75,\n \"completion_tokens\": + 51,\n \"total_tokens\": 126,\n \"prompt_tokens_details\": {\n \"cached_tokens\": + 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d87e6e7ba75dee2-SEA + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Sat, 26 Oct 2024 05:03:49 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1180' + openai-organization: test_organization + openai-processing-ms: + - '649' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '198' + x-ratelimit-remaining-tokens: + - '59961' + x-ratelimit-reset-requests: + - 14m23.304s + x-ratelimit-reset-tokens: + - 39ms + x-request-id: + - req_b2f085c19f19c32c8aa891887e228402 + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, + {"role": "user", "content": "What''s the weather in Seattle and San Francisco + today?"}, {"role": "assistant", "tool_calls": [{"id": "call_YBUn0S5ErhjkfnjFbWWJYIvR", + "function": {"arguments": "{\"location\": \"Seattle, WA\"}", "name": "get_current_weather"}, + "type": "function"}, {"id": "call_Ail5xuGFVRk2wUPidQWDYytn", "function": {"arguments": + "{\"location\": \"San Francisco, CA\"}", "name": "get_current_weather"}, "type": + "function"}]}, {"role": "tool", "content": "50 degrees and raining", "tool_call_id": + "call_YBUn0S5ErhjkfnjFbWWJYIvR"}, {"role": "tool", "content": "70 degrees and + sunny", "tool_call_id": "call_Ail5xuGFVRk2wUPidQWDYytn"}], "model": "gpt-4o-mini"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_set_cookie + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.52.2 + x-stainless-arch: + - other:amd64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - Windows + x-stainless-package-version: + - 1.52.2 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: "{\n \"id\": \"chatcmpl-AMTFlFwfqawbaH57GE3mXL8O17xo1\",\n \"object\": + \"chat.completion\",\n \"created\": 1729919029,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"Today, the weather in Seattle is 50 + degrees and raining, while in San Francisco, it is 70 degrees and sunny.\",\n + \ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": + \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 99,\n \"completion_tokens\": + 26,\n \"total_tokens\": 125,\n \"prompt_tokens_details\": {\n \"cached_tokens\": + 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8d87e6ec8ddedee2-SEA + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Sat, 26 Oct 2024 05:03:49 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '732' + openai-organization: test_organization + openai-processing-ms: + - '537' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '200' + x-ratelimit-limit-tokens: + - '60000' + x-ratelimit-remaining-requests: + - '197' + x-ratelimit-remaining-tokens: + - '59948' + x-ratelimit-reset-requests: + - 21m34.534s + x-ratelimit-reset-tokens: + - 52ms + x-request-id: + - req_ca78782b171f5cd60841ba443de92731 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion.yaml b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion.yaml rename to instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 976d58d7d8..1b79947cc5 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -5,8 +5,16 @@ import pytest from openai import OpenAI -from opentelemetry import trace from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor +from opentelemetry.instrumentation.openai_v2.utils import ( + OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT, +) +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, + SimpleLogRecordProcessor, +) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( @@ -14,21 +22,32 @@ ) -@pytest.fixture(scope="session") -def exporter(): +@pytest.fixture(scope="function", name="span_exporter") +def fixture_span_exporter(): exporter = InMemorySpanExporter() - processor = SimpleSpanProcessor(exporter) + yield exporter + + +@pytest.fixture(scope="function", name="log_exporter") +def fixture_log_exporter(): + exporter = InMemoryLogExporter() + yield exporter + +@pytest.fixture(scope="function", name="tracer_provider") +def fixture_tracer_provider(span_exporter): provider = TracerProvider() - provider.add_span_processor(processor) - trace.set_tracer_provider(provider) + provider.add_span_processor(SimpleSpanProcessor(span_exporter)) + return provider - return exporter +@pytest.fixture(scope="function", name="event_logger_provider") +def fixture_event_logger_provider(log_exporter): + provider = LoggerProvider() + provider.add_log_record_processor(SimpleLogRecordProcessor(log_exporter)) + event_logger_provider = EventLoggerProvider(provider) -@pytest.fixture(autouse=True) -def clear_exporter(exporter): - exporter.clear() + return event_logger_provider @pytest.fixture(autouse=True) @@ -51,14 +70,32 @@ def vcr_config(): } -@pytest.fixture(scope="session", autouse=True) -def instrument(): - OpenAIInstrumentor().instrument() - - -@pytest.fixture(scope="session", autouse=True) -def uninstrument(): - OpenAIInstrumentor().uninstrument() +@pytest.fixture(scope="function") +def instrument_no_content(tracer_provider, event_logger_provider): + instrumentor = OpenAIInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + event_logger_provider=event_logger_provider, + ) + + yield instrumentor + instrumentor.uninstrument() + + +@pytest.fixture(scope="function") +def instrument_with_content(tracer_provider, event_logger_provider): + os.environ.update( + {OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT: "True"} + ) + instrumentor = OpenAIInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + event_logger_provider=event_logger_provider, + ) + + yield instrumentor + os.environ.pop(OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT, None) + instrumentor.uninstrument() def scrub_response_headers(response): diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index 2b0f6a7f8c..be7bfc09b3 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -1,82 +1,390 @@ -import json +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# pylint: disable=too-many-locals + +from typing import Optional import pytest +from openai import OpenAI +from openai.resources.chat.completions import ChatCompletion +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.semconv._incubating.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + event_attributes as EventAttributes, +) from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) @pytest.mark.vcr() -def test_chat_completion(exporter, openai_client): - llm_model_value = "gpt-4" +def test_chat_completion_with_content( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" messages_value = [{"role": "user", "content": "Say this is a test"}] - kwargs = { - "model": llm_model_value, - "messages": messages_value, - "stream": False, + response = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - response = openai_client.chat.completions.create(**kwargs) - spans = exporter.get_finished_spans() - chat_completion_span = spans[0] - # assert that the span name is correct - assert chat_completion_span.name == f"chat {llm_model_value}" - - attributes = chat_completion_span.attributes - operation_name = attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] - system = attributes[GenAIAttributes.GEN_AI_SYSTEM] - request_model = attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] - response_model = attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] - response_id = attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] - input_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] - output_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] - # assert that the attributes are correct - assert ( - operation_name == GenAIAttributes.GenAiOperationNameValues.CHAT.value - ) - assert system == GenAIAttributes.GenAiSystemValues.OPENAI.value - assert request_model == llm_model_value - assert response_model == response.model - assert response_id == response.id - assert input_tokens == response.usage.prompt_tokens - assert output_tokens == response.usage.completion_tokens - - events = chat_completion_span.events - - # assert that the prompt and completion events are present - prompt_event = list( - filter( - lambda event: event.name == "gen_ai.content.prompt", - events, + +def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + client = OpenAI(base_url="http://localhost:4242") + + exception = None + try: + client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + timeout=0.1, ) + assert False, "Expected an exception" + except Exception as ex: # pylint: disable=broad-exception-caught + exception = ex + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, server_address="localhost" + ) + assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] + assert ( + type(exception).__qualname__ + == spans[0].attributes[ErrorAttributes.ERROR_TYPE] ) - completion_event = list( - filter( - lambda event: event.name == "gen_ai.content.completion", - events, + + +@pytest.mark.vcr() +def test_chat_completion_404( + span_exporter, openai_client, instrument_no_content +): + llm_model_value = "this-model-does-not-exist" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + exception = None + try: + openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + timeout=0.1, ) + assert False, "Expected an exception" + except Exception as ex: # pylint: disable=broad-exception-caught + exception = ex + + spans = span_exporter.get_finished_spans() + + assert_all_attributes(spans[0], llm_model_value) + assert ( + type(exception).__qualname__ + == spans[0].attributes[ErrorAttributes.ERROR_TYPE] ) - assert prompt_event - assert completion_event - # assert that the prompt and completion events have the correct attributes - assert prompt_event[0].attributes[ - GenAIAttributes.GEN_AI_PROMPT - ] == json.dumps(messages_value) +@pytest.mark.vcr() +def test_chat_completion_extra_params( + span_exporter, openai_client, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + seed=42, + temperature=0.5, + max_tokens=50, + stream=False, + extra_body={"service_tier": "default"}, + ) + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 + ) assert ( - json.loads( - completion_event[0].attributes[GenAIAttributes.GEN_AI_COMPLETION] - )[0]["content"] - == response.choices[0].message.content + spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + ) + assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] + == "default" + ) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_choices( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, n=2, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 # 1 user message + 2 choice messages + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[1].message.content, + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_tool_calls_with_content( + span_exporter, log_exporter, openai_client, instrument_with_content +): + chat_completion_tool_call(span_exporter, log_exporter, openai_client, True) + + +@pytest.mark.vcr() +def test_chat_completion_tool_calls_no_content( + span_exporter, log_exporter, openai_client, instrument_no_content +): + chat_completion_tool_call( + span_exporter, log_exporter, openai_client, False ) +def chat_completion_tool_call( + span_exporter, log_exporter, openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + ) + + # sanity check + assert "tool_calls" in response_0.choices[0].finish_reason + + # final request + messages_value.append( + { + "role": "assistant", + "tool_calls": response_0.choices[0].message.to_dict()[ + "tool_calls" + ], + } + ) + + tool_call_result_0 = { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": response_0.choices[0].message.tool_calls[0].id, + } + tool_call_result_1 = { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": response_0.choices[0].message.tool_calls[1].id, + } + + messages_value.append(tool_call_result_0) + messages_value.append(tool_call_result_1) + + response_1 = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value + ) + + # sanity check + assert "stop" in response_1.choices[0].finish_reason + + # validate both calls + spans = span_exporter.get_finished_spans() + assert len(spans) == 2 + assert_completion_attributes(spans[0], llm_model_value, response_0) + assert_completion_attributes(spans[1], llm_model_value, response_1) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 9 # 3 logs for first completion, 6 for second + + # call one + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + function_call_0 = {"name": "get_current_weather"} + function_call_1 = {"name": "get_current_weather"} + if expect_content: + function_call_0["arguments"] = ( + response_0.choices[0] + .message.tool_calls[0] + .function.arguments.replace("\n", "") + ) + function_call_1["arguments"] = ( + response_0.choices[0] + .message.tool_calls[1] + .function.arguments.replace("\n", "") + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": response_0.choices[0].message.tool_calls[0].id, + "type": "function", + "function": function_call_0, + }, + { + "id": response_0.choices[0].message.tool_calls[1].id, + "type": "function", + "function": function_call_1, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + # call two + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[3], "gen_ai.system.message", system_message, spans[1] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[4], "gen_ai.user.message", user_message, spans[1] + ) + + assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} + if not expect_content: + assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None + assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None + + assert_message_in_logs( + logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] + ) + + tool_message_0 = { + "id": tool_call_result_0["tool_call_id"], + "content": tool_call_result_0["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[6], "gen_ai.tool.message", tool_message_0, spans[1] + ) + + tool_message_1 = { + "id": tool_call_result_1["tool_call_id"], + "content": tool_call_result_1["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[7], "gen_ai.tool.message", tool_message_1, spans[1] + ) + + message = { + "role": "assistant", + "content": response_1.choices[0].message.content + if expect_content + else None, + } + choice = { + "index": 0, + "finish_reason": "stop", + "message": message, + } + assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) + + @pytest.mark.vcr() -def test_chat_completion_streaming(exporter, openai_client): +def test_chat_completion_streaming( + span_exporter, log_exporter, openai_client, instrument_with_content +): llm_model_value = "gpt-4" messages_value = [{"role": "user", "content": "Say this is a test"}] @@ -102,56 +410,428 @@ def test_chat_completion_streaming(exporter, openai_client): response_stream_model = chunk.model response_stream_id = chunk.id - spans = exporter.get_finished_spans() - streaming_span = spans[0] + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_streaming_not_complete( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + } + + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = openai_client.chat.completions.create(**kwargs) + for idx, chunk in enumerate(response): + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + if idx == 1: + # fake a stop + break + + if chunk.model: + response_stream_model = chunk.model + if chunk.id: + response_stream_id = chunk.id + + response.close() + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, response_stream_id, response_stream_model + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "error", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_choices_streaming( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + n=2, + stream=True, + stream_options={"include_usage": True}, + ) + + # two strings for each choice + response_stream_result = ["", ""] + finish_reasons = ["", ""] + for chunk in response_0: + if chunk.choices: + for choice in chunk.choices: + response_stream_result[choice.index] += ( + choice.delta.content or "" + ) + if choice.finish_reason: + finish_reasons[choice.index] = choice.finish_reason + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "stop" == finish_reasons[0] + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 4 + + system_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = { + "content": "What's the weather in Seattle and San Francisco today?" + } + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[0]), + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[1]), + }, + } + assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_tools_streaming_with_content( + span_exporter, log_exporter, openai_client, instrument_with_content +): + chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, openai_client, True + ) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_tools_streaming_no_content( + span_exporter, log_exporter, openai_client, instrument_no_content +): + chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, openai_client, False + ) + + +def chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + stream=True, + stream_options={"include_usage": True}, + ) + + finish_reason = None + # two tools + tool_names = ["", ""] + tool_call_ids = ["", ""] + tool_args = ["", ""] + for chunk in response: + if chunk.choices: + if chunk.choices[0].finish_reason: + finish_reason = chunk.choices[0].finish_reason + for tool_call in chunk.choices[0].delta.tool_calls or []: + t_idx = tool_call.index + if tool_call.id: + tool_call_ids[t_idx] = tool_call.id + if tool_call.function: + if tool_call.function.arguments: + tool_args[t_idx] += tool_call.function.arguments + if tool_call.function.name: + tool_names[t_idx] = tool_call.function.name + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "tool_calls" == finish_reason + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 - assert streaming_span.name == f"chat {llm_model_value}" - attributes = streaming_span.attributes + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": "What's the weather in Seattle and San Francisco today?"} + if expect_content + else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) - operation_name = attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] - system = attributes[GenAIAttributes.GEN_AI_SYSTEM] - request_model = attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] - response_model = attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] - response_id = attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] - input_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] - output_tokens = attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": tool_call_ids[0], + "type": "function", + "function": { + "name": tool_names[0], + "arguments": tool_args[0].replace("\n", "") + if expect_content + else None, + }, + }, + { + "id": tool_call_ids[1], + "type": "function", + "function": { + "name": tool_names[1], + "arguments": tool_args[1].replace("\n", "") + if expect_content + else None, + }, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + +def assert_message_in_logs(log, event_name, expected_content, parent_span): + assert log.log_record.attributes[EventAttributes.EVENT_NAME] == event_name assert ( - operation_name == GenAIAttributes.GenAiOperationNameValues.CHAT.value - ) - assert system == GenAIAttributes.GenAiSystemValues.OPENAI.value - assert request_model == llm_model_value - assert response_model == response_stream_model - assert response_id == response_stream_id - assert input_tokens == response_stream_usage.prompt_tokens - assert output_tokens == response_stream_usage.completion_tokens - - events = streaming_span.events - - # assert that the prompt and completion events are present - prompt_event = list( - filter( - lambda event: event.name == "gen_ai.content.prompt", - events, - ) + log.log_record.attributes[GenAIAttributes.GEN_AI_SYSTEM] + == GenAIAttributes.GenAiSystemValues.OPENAI.value ) - completion_event = list( - filter( - lambda event: event.name == "gen_ai.content.completion", - events, + + if not expected_content: + assert not log.log_record.body + else: + assert dict(log.log_record.body) == remove_none_values( + expected_content ) - ) + assert_log_parent(log, parent_span) + - assert prompt_event - assert completion_event +def remove_none_values(body): + result = {} + for key, value in body.items(): + if value is None: + continue + if isinstance(value, dict): + result[key] = remove_none_values(value) + elif isinstance(value, list): + result[key] = [remove_none_values(i) for i in value] + else: + result[key] = value + return result - # assert that the prompt and completion events have the correct attributes - assert prompt_event[0].attributes[ - GenAIAttributes.GEN_AI_PROMPT - ] == json.dumps(messages_value) +def assert_completion_attributes( + span: ReadableSpan, + request_model: str, + response: ChatCompletion, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + return assert_all_attributes( + span, + request_model, + response.id, + response.model, + response.usage.prompt_tokens, + response.usage.completion_tokens, + operation_name, + server_address, + ) + + +def assert_all_attributes( + span: ReadableSpan, + request_model: str, + response_id: str = None, + response_model: str = None, + input_tokens: Optional[int] = None, + output_tokens: Optional[int] = None, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + assert span.name == f"{operation_name} {request_model}" + assert ( + operation_name + == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + ) + assert ( + GenAIAttributes.GenAiSystemValues.OPENAI.value + == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] + ) assert ( - json.loads( - completion_event[0].attributes[GenAIAttributes.GEN_AI_COMPLETION] - )[0]["content"] - == response_stream_result + request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] ) + if response_model: + assert ( + response_model + == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL not in span.attributes + + if response_id: + assert ( + response_id == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_ID not in span.attributes + + if input_tokens: + assert ( + input_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + ) + else: + assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS not in span.attributes + + if output_tokens: + assert ( + output_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + ) + else: + assert ( + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS not in span.attributes + ) + + assert server_address == span.attributes[ServerAttributes.SERVER_ADDRESS] + + +def assert_log_parent(log, span): + assert log.log_record.trace_id == span.get_span_context().trace_id + assert log.log_record.span_id == span.get_span_context().span_id + assert log.log_record.trace_flags == span.get_span_context().trace_flags + + +def get_current_weather_tool_definition(): + return { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA", + }, + }, + "required": ["location"], + "additionalProperties": False, + }, + }, + } diff --git a/tox.ini b/tox.ini index 62c205513e..53c55561b6 100644 --- a/tox.ini +++ b/tox.ini @@ -910,6 +910,9 @@ commands = test-instrumentation-mysqlclient: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/tests {posargs} lint-instrumentation-mysqlclient: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysqlclient" + test-instrumentation-openai-v2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-openai-v2/tests {posargs} + lint-instrumentation-openai-v2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-openai-v2" + test-instrumentation-sio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests {posargs} lint-instrumentation-sio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pika" From 3109724f48c36ecc573d6959fe4743c8a1afd941 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 4 Nov 2024 06:18:11 -0800 Subject: [PATCH 211/335] Add genai contributing guidance (#2944) --- .github/component_owners.yml | 5 +++++ CONTRIBUTING.md | 13 +++++++++++++ README.md | 2 +- .../CHANGELOG.md | 0 .../opentelemetry-instrumentation-openai-v2/LICENSE | 0 .../README.rst | 0 .../pyproject.toml | 0 .../instrumentation/openai_v2/__init__.py | 0 .../instrumentation/openai_v2/package.py | 0 .../instrumentation/openai_v2/patch.py | 0 .../instrumentation/openai_v2/utils.py | 0 .../instrumentation/openai_v2/version.py | 0 .../test-requirements.txt | 2 +- .../tests/__init__.py | 0 .../tests/cassettes/test_chat_completion_404.yaml | 0 .../test_chat_completion_extra_params.yaml | 0 .../test_chat_completion_multiple_choices.yaml | 0 ..._chat_completion_multiple_choices_streaming.yaml | 0 ...pletion_multiple_tools_streaming_no_content.yaml | 0 ...etion_multiple_tools_streaming_with_content.yaml | 0 .../cassettes/test_chat_completion_streaming.yaml | 0 ...test_chat_completion_streaming_not_complete.yaml | 0 .../test_chat_completion_tool_calls_no_content.yaml | 0 ...est_chat_completion_tool_calls_with_content.yaml | 0 .../test_chat_completion_with_content.yaml | 0 .../tests/conftest.py | 0 .../tests/test_chat_completions.py | 0 instrumentation/README.md | 1 - .../pyproject.toml | 1 - .../opentelemetry/instrumentation/bootstrap_gen.py | 4 ---- tox.ini | 8 ++++---- 31 files changed, 24 insertions(+), 12 deletions(-) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/CHANGELOG.md (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/LICENSE (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/README.rst (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/pyproject.toml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/test-requirements.txt (72%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/__init__.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/conftest.py (100%) rename {instrumentation => instrumentation-genai}/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py (100%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index dcc1013476..621e00b005 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -66,3 +66,8 @@ components: processor/opentelemetry-processor-baggage: - codeboten + + instrumentation-genai/: + - karthikscale3 + - lmolkova + - lzchen diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8d72683692..798b1ef571 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,6 +34,7 @@ Please also read the [OpenTelemetry Contributor Guide](https://github.com/open-t * [Testing against a different Core repo branch/commit](#testing-against-a-different-core-repo-branchcommit) * [Style Guide](#style-guide) * [Guideline for instrumentations](#guideline-for-instrumentations) +* [Guidance for GenAI instrumentations](#guideline-for-genai-instrumentations) * [Expectations from contributors](#expectations-from-contributors) ## Find a Buddy and get Started Quickly @@ -272,6 +273,18 @@ Below is a checklist of things to be mindful of when implementing a new instrume - ex. - All instrumentations have the same version. If you are going to develop a new instrumentation it would probably have `X.Y.dev` version and depends on `opentelemetry-instrumentation` and `opentelemetry-semantic-conventions` for the same version. That means that if you want to install your instrumentation you need to install its dependencies from this repo and the core repo also from git. +## Guidance for GenAI instrumentations + +Instrumentations that relate to [Generative AI](https://opentelemetry.io/docs/specs/semconv/gen-ai/) systems will be placed in the [genai](./instrumentation/genai) folder. This section covers contributions related to those instrumentations. Please note that the [guidelines for instrumentations](#guideline-for-instrumentations) and [expectations from contributors](#expectations-from-contributors) still apply. + +### Get Involved + +* Reviewing PRs: If you would like to be tagged as reviewer in new PRs related to these instrumentations, please submit a PR to add your GitHub handle to [component_owners.yml](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2944/.github/component_owners.yml) under the corresponding instrumentation folder(s). + +* Approving PRs: If you would like to be able to approve PRs related to these instrumentations, you must join [opentelemetry-python-contrib-approvers](https://github.com/orgs/open-telemetry/teams/opentelemetry-python-contrib-approvers) team. Please ask one of the [Python contrib maintainers](https://github.com/orgs/open-telemetry/teams/opentelemetry-python-contrib-maintainers) to be accepted into the team. + +* Tracking and Creating Issues: For tracking issues related to Generative AI, please filter or add the label [gen-ai](https://github.com/open-telemetry/opentelemetry-python-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Agen-ai) when creating or searching issues. If you do not see an issue related to an instrumentation you would like to contribute to, please create a new tracking issue so the community is aware of its progress. + ## Expectations from contributors OpenTelemetry is an open source community, and as such, greatly encourages contributions from anyone interested in the project. With that being said, there is a certain level of expectation from contributors even after a pull request is merged, specifically pertaining to instrumentations. The OpenTelemetry Python community expects contributors to maintain a level of support and interest in the instrumentations they contribute. This is to ensure that the instrumentation does not become stale and still functions the way the original contributor intended. Some instrumentations also pertain to libraries that the current members of the community are not so familiar with, so it is necessary to rely on the expertise of the original contributing parties. diff --git a/README.md b/README.md index a04c4b7c7b..8582c472ba 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,6 @@ Emeritus Approvers: Maintainers ([@open-telemetry/python-maintainers](https://github.com/orgs/open-telemetry/teams/python-maintainers)): - [Aaron Abbott](https://github.com/aabmass), Google -- [Diego Hurtado](https://github.com/ocelotl), Lightstep - [Leighton Chen](https://github.com/lzchen), Microsoft - [Riccardo Magliocchetti](https://github.com/xrmx), Elastic - [Shalev Roda](https://github.com/shalevr), Cisco @@ -141,6 +140,7 @@ Maintainers ([@open-telemetry/python-maintainers](https://github.com/orgs/open-t Emeritus Maintainers: - [Alex Boten](https://github.com/codeboten), Lightstep +- [Diego Hurtado](https://github.com/ocelotl), Lightstep - [Owais Lone](https://github.com/owais), Splunk - [Yusuke Tsutsumi](https://github.com/toumorokoshi), Google diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/CHANGELOG.md rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/LICENSE b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/LICENSE similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/LICENSE rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/LICENSE diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/README.rst rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/pyproject.toml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt similarity index 72% rename from instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt index a3d7402a9c..09a7c75c16 100644 --- a/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt @@ -8,4 +8,4 @@ pytest-vcr==1.0.2 wrapt==1.16.0 -e opentelemetry-instrumentation --e instrumentation/opentelemetry-instrumentation-openai-v2 +-e instrumentation-genai/opentelemetry-instrumentation-openai-v2 diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/__init__.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/__init__.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/__init__.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py diff --git a/instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py diff --git a/instrumentation/README.md b/instrumentation/README.md index db437fe518..6bb47f6f9c 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -29,7 +29,6 @@ | [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging | No | experimental | [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python >= 8.0, < 10.0 | No | experimental | [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | experimental -| [opentelemetry-instrumentation-openai-v2](./opentelemetry-instrumentation-openai-v2) | openai >= 1.26.0 | No | experimental | [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 | No | experimental | [opentelemetry-instrumentation-psycopg](./opentelemetry-instrumentation-psycopg) | psycopg >= 3.1.0 | No | experimental | [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1 | No | experimental diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 2b6b2cfedb..b34226b669 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -57,7 +57,6 @@ dependencies = [ "opentelemetry-instrumentation-logging==0.49b0.dev", "opentelemetry-instrumentation-mysql==0.49b0.dev", "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", - "opentelemetry-instrumentation-openai-v2==2.0.0.dev", "opentelemetry-instrumentation-pika==0.49b0.dev", "opentelemetry-instrumentation-psycopg==0.49b0.dev", "opentelemetry-instrumentation-psycopg2==0.49b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 95d25026f9..ff6065d058 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -120,10 +120,6 @@ "library": "mysqlclient < 3", "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", }, - { - "library": "openai >= 1.0.0", - "instrumentation": "opentelemetry-instrumentation-openai-v2==2.0.0.dev", - }, { "library": "pika >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-pika==0.49b0.dev", diff --git a/tox.ini b/tox.ini index 53c55561b6..62eeb03be2 100644 --- a/tox.ini +++ b/tox.ini @@ -414,7 +414,7 @@ commands_pre = openai: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions openai: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk openai: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - openai: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt + openai: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt distro: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api distro: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -471,7 +471,7 @@ commands_pre = openai: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api openai: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk openai: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - openai: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-openai-v2/test-requirements.txt + openai: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt confluent-kafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api confluent-kafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -910,8 +910,8 @@ commands = test-instrumentation-mysqlclient: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/tests {posargs} lint-instrumentation-mysqlclient: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysqlclient" - test-instrumentation-openai-v2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-openai-v2/tests {posargs} - lint-instrumentation-openai-v2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-openai-v2" + test-instrumentation-openai-v2: pytest {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests {posargs} + lint-instrumentation-openai-v2: sh -c "cd instrumentation-genai && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-openai-v2" test-instrumentation-sio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests {posargs} lint-instrumentation-sio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pika" From 155962b4423115100b5fcc310ddf32edcaa8cbfe Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 4 Nov 2024 12:27:42 -0800 Subject: [PATCH 212/335] GenAI: Use common env var for content recording (#2947) --- .../opentelemetry-instrumentation-openai-v2/CHANGELOG.md | 4 ++++ .../src/opentelemetry/instrumentation/openai_v2/utils.py | 6 +++--- .../tests/conftest.py | 6 +++--- .../tests/test_chat_completions.py | 1 + 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 3509eb5b79..16ecbdaefe 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Use generic `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` environment variable + to control if content of prompt, completion, and other messages is captured. + ([#2947](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2947)) + - Update OpenAI instrumentation to Semantic Conventions v1.28.0: add new attributes and switch prompts and completions to log-based events. ([#2925](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2925)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index ffbf3db5aa..a3a2d317ce 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -27,14 +27,14 @@ server_attributes as ServerAttributes, ) -OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT = ( - "OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT" +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = ( + "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" ) def is_content_enabled() -> bool: capture_content = environ.get( - OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT, "false" + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, "false" ) return capture_content.lower() == "true" diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 1b79947cc5..f35dfbacf2 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -7,7 +7,7 @@ from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor from opentelemetry.instrumentation.openai_v2.utils import ( - OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT, + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, ) from opentelemetry.sdk._events import EventLoggerProvider from opentelemetry.sdk._logs import LoggerProvider @@ -85,7 +85,7 @@ def instrument_no_content(tracer_provider, event_logger_provider): @pytest.fixture(scope="function") def instrument_with_content(tracer_provider, event_logger_provider): os.environ.update( - {OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT: "True"} + {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} ) instrumentor = OpenAIInstrumentor() instrumentor.instrument( @@ -94,7 +94,7 @@ def instrument_with_content(tracer_provider, event_logger_provider): ) yield instrumentor - os.environ.pop(OTEL_INSTRUMENTATION_OPENAI_CAPTURE_MESSAGE_CONTENT, None) + os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) instrumentor.uninstrument() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index be7bfc09b3..4369aa6a38 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -713,6 +713,7 @@ def assert_message_in_logs(log, event_name, expected_content, parent_span): if not expected_content: assert not log.log_record.body else: + assert log.log_record.body assert dict(log.log_record.body) == remove_none_values( expected_content ) From d6a59e4bdf076ad5e0c71cb8a21bdb514f769bda Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:21:59 +0800 Subject: [PATCH 213/335] opentelemetry-instrumentation-openai-v2: format test data for readability (#2945) * opentelemetry-instrumentation-openai-v2: format test data as YAML literal block scalar for readability Signed-off-by: Adrian Cole * ruff Signed-off-by: Adrian Cole * Update instrumentation/opentelemetry-instrumentation-openai-v2/tests/conftest.py Co-authored-by: Riccardo Magliocchetti --------- Signed-off-by: Adrian Cole Co-authored-by: Riccardo Magliocchetti --- .../cassettes/test_chat_completion_404.yaml | 42 +- .../test_chat_completion_extra_params.yaml | 94 ++-- ...test_chat_completion_multiple_choices.yaml | 99 ++-- ...completion_multiple_choices_streaming.yaml | 457 ++++++------------ ...n_multiple_tools_streaming_no_content.yaml | 145 +++--- ...multiple_tools_streaming_with_content.yaml | 145 +++--- .../test_chat_completion_streaming.yaml | 70 +-- ...hat_completion_streaming_not_complete.yaml | 71 ++- ...chat_completion_tool_calls_no_content.yaml | 276 ++++++++--- ...at_completion_tool_calls_with_content.yaml | 276 ++++++++--- .../test_chat_completion_with_content.yaml | 80 ++- .../tests/conftest.py | 69 +++ .../tests/test_chat_completions.py | 23 +- 13 files changed, 1052 insertions(+), 795 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml index 1b7a7988ca..ae00c6ef70 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml @@ -1,7 +1,15 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": - "this-model-does-not-exist"}' + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "this-model-does-not-exist" + } headers: accept: - application/json @@ -16,41 +24,45 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '2' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"error\": {\n \"message\": \"The model `this-model-does-not-exist` - does not exist or you do not have access to it.\",\n \"type\": \"invalid_request_error\",\n - \ \"param\": null,\n \"code\": \"model_not_found\"\n }\n}\n" + string: |- + { + "error": { + "message": "The model `this-model-does-not-exist` does not exist or you do not have access to it.", + "type": "invalid_request_error", + "param": null, + "code": "model_not_found" + } + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d88b04c2c5db9eb-SEA + - 8dd0709dffd19c8c-SIN Connection: - keep-alive Content-Type: - application/json; charset=utf-8 Date: - - Sat, 26 Oct 2024 07:21:17 GMT + - Mon, 04 Nov 2024 00:20:44 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -68,7 +80,7 @@ interactions: vary: - Origin x-request-id: - - req_8529656422f0360e8bcba8c2b8fe34e9 + - req_e08854c4f7d5104af6fdc755caed30fc status: code: 404 message: Not Found diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml index 75903a6a55..cfcd27074a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml @@ -1,8 +1,20 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": - "gpt-4o-mini", "max_tokens": 50, "seed": 42, "service_tier": "auto", "stream": - false, "temperature": 0.5}' + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "max_tokens": 50, + "seed": 42, + "stream": false, + "temperature": 0.5, + "service_tier": "default" + } headers: accept: - application/json @@ -11,54 +23,74 @@ interactions: connection: - keep-alive content-length: - - '180' + - '183' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AMTlCEj20ZcsgWKZt8EizFMDItWNf\",\n \"object\": - \"chat.completion\",\n \"created\": 1729920978,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"This is a test. How can I assist you - further?\",\n \"refusal\": null\n },\n \"logprobs\": null,\n - \ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": - 12,\n \"completion_tokens\": 12,\n \"total_tokens\": 24,\n \"prompt_tokens_details\": - {\n \"cached_tokens\": 0\n },\n \"completion_tokens_details\": - {\n \"reasoning_tokens\": 0\n }\n },\n \"service_tier\": \"default\",\n - \ \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + string: |- + { + "id": "chatcmpl-APfFNvBVQx43PNOIf1dWnEUT5u5fA", + "object": "chat.completion", + "created": 1730680117, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d881682197c7571-SEA + - 8dd07c2d0a5a9f98-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Sat, 26 Oct 2024 05:36:18 GMT + - Mon, 04 Nov 2024 00:28:37 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -74,25 +106,25 @@ interactions: - '697' openai-organization: test_organization openai-processing-ms: - - '275' + - '228' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '195' + - '9998' x-ratelimit-remaining-tokens: - - '59944' + - '199943' x-ratelimit-reset-requests: - - 32m17.492s + - 13.724s x-ratelimit-reset-tokens: - - 56ms + - 16ms x-request-id: - - req_181075e8f861d6685fe1ae5d4bfc9b25 + - req_0ded46a4535c24c36ef58363b7538421 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml index 2416a06cb8..9518e41225 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml @@ -1,7 +1,17 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": - "gpt-4o-mini", "n": 2, "stream": false}' + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": false + } headers: accept: - application/json @@ -16,50 +26,77 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AMT4dWD9gi2PyDcXBK10harskeREO\",\n \"object\": - \"chat.completion\",\n \"created\": 1729918339,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"This is a test.\",\n \"refusal\": - null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n - \ },\n {\n \"index\": 1,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"This is a test. How can I assist you - further?\",\n \"refusal\": null\n },\n \"logprobs\": null,\n - \ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": - 12,\n \"completion_tokens\": 17,\n \"total_tokens\": 29,\n \"prompt_tokens_details\": - {\n \"cached_tokens\": 0\n },\n \"completion_tokens_details\": - {\n \"reasoning_tokens\": 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + string: |- + { + "id": "chatcmpl-APfFO3w0cNVOphe5Lk9EaYyRaS2pm", + "object": "chat.completion", + "created": 1730680118, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + }, + { + "index": 1, + "message": { + "role": "assistant", + "content": "This is a test! How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 17, + "total_tokens": 29, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d87d6120a899357-SEA + - 8dd07c30beda3dd4-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Sat, 26 Oct 2024 04:52:19 GMT + - Mon, 04 Nov 2024 00:28:38 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -75,25 +112,25 @@ interactions: - '872' openai-organization: test_organization openai-processing-ms: - - '664' + - '261' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '199' + - '9997' x-ratelimit-remaining-tokens: - - '59962' + - '199962' x-ratelimit-reset-requests: - - 7m12s + - 21.785s x-ratelimit-reset-tokens: - - 38ms + - 11ms x-request-id: - - req_d8b7a2507994f22fe0d4511c7e0a3bdc + - req_86ab6a7a85f95e2a001cfeb89e0827b1 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml index c5be0fa9d4..e587ce5a38 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml @@ -1,9 +1,24 @@ interactions: - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}], "model": "gpt-4o-mini", "n": 2, "stream": true, "stream_options": - {"include_usage": true}}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": true, + "stream_options": { + "include_usage": true + } + } headers: accept: - application/json @@ -18,441 +33,271 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: 'data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + string: |+ + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"I''m"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"I''m"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - unable"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - sorry"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - provide"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - but"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" For"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - real"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - I"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" most"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" accurate"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - can''t"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" up"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - provide"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - updates"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - real"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-to"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-date"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - However"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" please"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - updates"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" reliable"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - you"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - as"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - can"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - my"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - easily"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - training"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" You"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - check"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - data"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" use"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - goes"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Channel"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - current"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" search"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - up"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Acc"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" engine"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"u"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - in"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"Weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" service"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - October"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" immediate"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - "},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - and"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" local"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" news"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - San"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" station"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"'s"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - and"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" If"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - using"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" there's"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"'s"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - I"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" anything"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" else"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you'd"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - websites"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" today"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - like"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" know"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - don''t"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" feel"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" free"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - have"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - access"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - to"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - Weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - live"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - Channel"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - data"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - Acc"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"u"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"Weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - I"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - recommend"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - checking"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - a"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - reliable"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - website"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - or"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - using"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - a"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - or"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - a"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - app"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - on"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - your"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":" - smartphone"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - app"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - for"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - the"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - most"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - current"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - information"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - on"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - the"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - in"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - and"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - San"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":" - Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - - data: {"id":"chatcmpl-AMUBWEnUmLx8XIYS8oNiZopa2WpJf","object":"chat.completion.chunk","created":1729922610,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":100,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":111,"total_tokens":137,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} data: [DONE] - - ' headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d883e57eb7227f9-SEA + - 8dd07c55783bce06-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Sat, 26 Oct 2024 06:03:30 GMT + - Mon, 04 Nov 2024 00:28:44 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -466,25 +311,25 @@ interactions: - h3=":443"; ma=86400 openai-organization: test_organization openai-processing-ms: - - '216' + - '127' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '194' + - '9993' x-ratelimit-remaining-tokens: - - '59945' + - '199945' x-ratelimit-reset-requests: - - 41m5.83s + - 59.105s x-ratelimit-reset-tokens: - - 55ms + - 16ms x-request-id: - - req_2cafe46d3edfcc0f61e4885c27cca46e + - req_4d50387aa59e08f2dc486aa5c62613f5 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml index 86085d12cf..8989eb9cfa 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml @@ -1,13 +1,46 @@ interactions: - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "stream": true, - "stream_options": {"include_usage": true}, "tool_choice": "auto", "tools": [{"type": - "function", "function": {"name": "get_current_weather", "description": "Get - the current weather in a given location", "parameters": {"type": "object", "properties": - {"location": {"type": "string", "description": "The city and state, e.g. Boston, - MA"}}, "required": ["location"], "additionalProperties": false}}}]}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } headers: accept: - application/json @@ -16,107 +49,81 @@ interactions: connection: - keep-alive content-length: - - '631' + - '602' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: 'data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + string: |+ + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_H7ADtKo1DKIzNyrCSBt1jKdw","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_yy3bBunEUS0C3HGZECG9EGCj","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": - \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_Dmv04Iin9mOpBKWSwdb5DbpS","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, - W"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ug3IE7qMdaP4tBJwJHacc7GO","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": - \"S"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an - F"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, - C"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} data: [DONE] - - ' headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d887ec3b9047639-SEA + - 8dd07c715fd66beb-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Sat, 26 Oct 2024 06:47:29 GMT + - Mon, 04 Nov 2024 00:28:49 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -130,25 +137,25 @@ interactions: - h3=":443"; ma=86400 openai-organization: test_organization openai-processing-ms: - - '723' + - '647' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '197' + - '9991' x-ratelimit-remaining-tokens: - - '59961' + - '199961' x-ratelimit-reset-requests: - - 18m43.156s + - 1m11.934s x-ratelimit-reset-tokens: - - 39ms + - 11ms x-request-id: - - req_81b3cd6dbe38ffddcdca90c699f71f84 + - req_66ecdeba3a9e89bbc2aa60243fb1fdfb status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml index 86085d12cf..c39facccc5 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml @@ -1,13 +1,46 @@ interactions: - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "stream": true, - "stream_options": {"include_usage": true}, "tool_choice": "auto", "tools": [{"type": - "function", "function": {"name": "get_current_weather", "description": "Get - the current weather in a given location", "parameters": {"type": "object", "properties": - {"location": {"type": "string", "description": "The city and state, e.g. Boston, - MA"}}, "required": ["location"], "additionalProperties": false}}}]}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } headers: accept: - application/json @@ -16,107 +49,81 @@ interactions: connection: - keep-alive content-length: - - '631' + - '602' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: 'data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + string: |+ + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_CqwFQqzbiNttzDzEXiUitRos","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_yy3bBunEUS0C3HGZECG9EGCj","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": - \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_SGVgEhhsqfE7s6MOHSXwKSGG","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, - W"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ug3IE7qMdaP4tBJwJHacc7GO","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": - \"S"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an - F"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, - C"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - - - data: {"id":"chatcmpl-AMUs4TXmQG6Rbn1KXpwESVDmy6eoL","object":"chat.completion.chunk","created":1729925248,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_f59a81427f","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} data: [DONE] - - ' headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d887ec3b9047639-SEA + - 8dd07c5d48f0ce22-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Sat, 26 Oct 2024 06:47:29 GMT + - Mon, 04 Nov 2024 00:28:48 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -130,25 +137,25 @@ interactions: - h3=":443"; ma=86400 openai-organization: test_organization openai-processing-ms: - - '723' + - '2886' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '197' + - '9992' x-ratelimit-remaining-tokens: - - '59961' + - '199961' x-ratelimit-reset-requests: - - 18m43.156s + - 1m6.499s x-ratelimit-reset-tokens: - - 39ms + - 11ms x-request-id: - - req_81b3cd6dbe38ffddcdca90c699f71f84 + - req_c887b8540fec8e4eadca5d56c78cc4e1 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml index c61133739b..713ea762e0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml @@ -1,7 +1,19 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": - "gpt-4", "stream": true, "stream_options": {"include_usage": true}}' + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true, + "stream_options": { + "include_usage": true + } + } headers: accept: - application/json @@ -16,7 +28,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.47.0 + - OpenAI/Python 1.26.0 x-stainless-arch: - arm64 x-stainless-async: @@ -26,57 +38,45 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.47.0 + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.11.5 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: 'data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + string: |+ + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" - is"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" - a"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" - test"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - - data: {"id":"chatcmpl-AC6akONKCxc8HS63qZ08HyjeTSq6p","object":"chat.completion.chunk","created":1727448638,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} data: [DONE] - - ' headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8c9c4ea489d57948-PMO + - 8dd07c4b99b74927-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Fri, 27 Sep 2024 14:50:38 GMT + - Mon, 04 Nov 2024 00:28:42 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -86,9 +86,11 @@ interactions: - nosniff access-control-expose-headers: - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 openai-organization: test_organization openai-processing-ms: - - '161' + - '157' openai-version: - '2020-10-01' strict-transport-security: @@ -96,17 +98,17 @@ interactions: x-ratelimit-limit-requests: - '10000' x-ratelimit-limit-tokens: - - '1000000' + - '10000' x-ratelimit-remaining-requests: - '9999' x-ratelimit-remaining-tokens: - - '999977' + - '9978' x-ratelimit-reset-requests: - - 6ms + - 8.64s x-ratelimit-reset-tokens: - - 1ms + - 132ms x-request-id: - - req_3fa9ac9f3693c712e4c377e26d203e58 + - req_72de20dac77a9535e3f47a6ec3a39ddc status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml index ea683057c3..bec0658770 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml @@ -1,7 +1,16 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": - "gpt-4", "stream": true, "stream_options": {"include_usage": true}}' + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true + } headers: accept: - application/json @@ -10,75 +19,59 @@ interactions: connection: - keep-alive content-length: - - '142' + - '99' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: 'data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + string: |+ + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" - is"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" - a"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" - test"},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - - data: {"id":"chatcmpl-AMVXI9sDOpHDCsGW99OJ6fYqHSu0J","object":"chat.completion.chunk","created":1729927804,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} - + data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} data: [DONE] - - ' headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d88bd2c0d9e308c-SEA + - 8dd07c505e24cdf2-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Sat, 26 Oct 2024 07:30:05 GMT + - Mon, 04 Nov 2024 00:28:43 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -92,25 +85,25 @@ interactions: - h3=":443"; ma=86400 openai-organization: test_organization openai-processing-ms: - - '176' + - '269' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - '10000' x-ratelimit-remaining-requests: - - '199' + - '9998' x-ratelimit-remaining-tokens: - '9978' x-ratelimit-reset-requests: - - 7m12s + - 16.502s x-ratelimit-reset-tokens: - 132ms x-request-id: - - req_6ff271d00318adcd2408d8dcd5f93ec7 + - req_04c174debe2eace86b1e2777d7ac7265 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml index 9a8b489489..b4d5acca4a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml @@ -1,13 +1,42 @@ interactions: - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "tool_choice": - "auto", "tools": [{"type": "function", "function": {"name": "get_current_weather", - "description": "Get the current weather in a given location", "parameters": - {"type": "object", "properties": {"location": {"type": "string", "description": - "The city and state, e.g. Boston, MA"}}, "required": ["location"], "additionalProperties": - false}}}]}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } headers: accept: - application/json @@ -16,60 +45,91 @@ interactions: connection: - keep-alive content-length: - - '572' + - '543' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AMTFkpz8qllCCkh1A8xzoe14DwAQN\",\n \"object\": - \"chat.completion\",\n \"created\": 1729919028,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": null,\n \"tool_calls\": [\n {\n - \ \"id\": \"call_YBUn0S5ErhjkfnjFbWWJYIvR\",\n \"type\": - \"function\",\n \"function\": {\n \"name\": \"get_current_weather\",\n - \ \"arguments\": \"{\\\"location\\\": \\\"Seattle, WA\\\"}\"\n - \ }\n },\n {\n \"id\": \"call_Ail5xuGFVRk2wUPidQWDYytn\",\n - \ \"type\": \"function\",\n \"function\": {\n \"name\": - \"get_current_weather\",\n \"arguments\": \"{\\\"location\\\": - \\\"San Francisco, CA\\\"}\"\n }\n }\n ],\n \"refusal\": - null\n },\n \"logprobs\": null,\n \"finish_reason\": \"tool_calls\"\n - \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 75,\n \"completion_tokens\": - 51,\n \"total_tokens\": 126,\n \"prompt_tokens_details\": {\n \"cached_tokens\": - 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": - 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + string: |- + { + "id": "chatcmpl-APfFQZB7CuqkWhGyMZegJZRX2Mqv7", + "object": "chat.completion", + "created": 1730680120, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_SBoEJuTov3qHLothPvvgZyO6", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_2nL8HxSquLkKxpTENiZ17ynv", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d87e6e7ba75dee2-SEA + - 8dd07c3f4ba7ce35-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Sat, 26 Oct 2024 05:03:49 GMT + - Mon, 04 Nov 2024 00:28:41 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -85,38 +145,74 @@ interactions: - '1180' openai-organization: test_organization openai-processing-ms: - - '649' + - '984' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '198' + - '9994' x-ratelimit-remaining-tokens: - - '59961' + - '199961' x-ratelimit-reset-requests: - - 14m23.304s + - 45.38s x-ratelimit-reset-tokens: - - 39ms + - 11ms x-request-id: - - req_b2f085c19f19c32c8aa891887e228402 + - req_af3dca7532583ed0a68645314bcc9be0 status: code: 200 message: OK - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}, {"role": "assistant", "tool_calls": [{"id": "call_YBUn0S5ErhjkfnjFbWWJYIvR", - "function": {"arguments": "{\"location\": \"Seattle, WA\"}", "name": "get_current_weather"}, - "type": "function"}, {"id": "call_Ail5xuGFVRk2wUPidQWDYytn", "function": {"arguments": - "{\"location\": \"San Francisco, CA\"}", "name": "get_current_weather"}, "type": - "function"}]}, {"role": "tool", "content": "50 degrees and raining", "tool_call_id": - "call_YBUn0S5ErhjkfnjFbWWJYIvR"}, {"role": "tool", "content": "70 degrees and - sunny", "tool_call_id": "call_Ail5xuGFVRk2wUPidQWDYytn"}], "model": "gpt-4o-mini"}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_SBoEJuTov3qHLothPvvgZyO6", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_2nL8HxSquLkKxpTENiZ17ynv", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_SBoEJuTov3qHLothPvvgZyO6" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_2nL8HxSquLkKxpTENiZ17ynv" + } + ], + "model": "gpt-4o-mini" + } headers: accept: - application/json @@ -129,52 +225,72 @@ interactions: content-type: - application/json cookie: - - test_set_cookie + - __cf_bm=moy9FTa50Ug99_ZQaP2atn.PgzKoQyF7pvWqG_CIf54-1730680121-1.0.1.1-mczyecbBSU5hWl8uat1lcU6ya1g6MY.Oso_vHVilj7O8C2RJrObTEyzD5DAMphUCFqBYVGHMurXg16CMssvuNw; + _cfuvid=FpMMQOb0sz4wVuQI7b1RY2KJKVNyHctKOqsWAL4tph0-1730680121454-0.0.1.1-604800000 host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AMTFlFwfqawbaH57GE3mXL8O17xo1\",\n \"object\": - \"chat.completion\",\n \"created\": 1729919029,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"Today, the weather in Seattle is 50 - degrees and raining, while in San Francisco, it is 70 degrees and sunny.\",\n - \ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": - \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 99,\n \"completion_tokens\": - 26,\n \"total_tokens\": 125,\n \"prompt_tokens_details\": {\n \"cached_tokens\": - 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": - 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + string: |- + { + "id": "chatcmpl-APfFRbb22UJc07TGY9KcrrWO5fs9c", + "object": "chat.completion", + "created": 1730680121, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 25, + "total_tokens": 124, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d87e6ec8ddedee2-SEA + - 8dd07c473cc4ce35-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Sat, 26 Oct 2024 05:03:49 GMT + - Mon, 04 Nov 2024 00:28:42 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -187,28 +303,28 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '732' + - '731' openai-organization: test_organization openai-processing-ms: - - '537' + - '380' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '197' + - '9993' x-ratelimit-remaining-tokens: - - '59948' + - '199947' x-ratelimit-reset-requests: - - 21m34.534s + - 52.749s x-ratelimit-reset-tokens: - - 52ms + - 15ms x-request-id: - - req_ca78782b171f5cd60841ba443de92731 + - req_f56de3d8b168900542a01b971b367a9f status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml index 9a8b489489..fbf1abd640 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml @@ -1,13 +1,42 @@ interactions: - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}], "model": "gpt-4o-mini", "parallel_tool_calls": true, "tool_choice": - "auto", "tools": [{"type": "function", "function": {"name": "get_current_weather", - "description": "Get the current weather in a given location", "parameters": - {"type": "object", "properties": {"location": {"type": "string", "description": - "The city and state, e.g. Boston, MA"}}, "required": ["location"], "additionalProperties": - false}}}]}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } headers: accept: - application/json @@ -16,60 +45,91 @@ interactions: connection: - keep-alive content-length: - - '572' + - '543' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AMTFkpz8qllCCkh1A8xzoe14DwAQN\",\n \"object\": - \"chat.completion\",\n \"created\": 1729919028,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": null,\n \"tool_calls\": [\n {\n - \ \"id\": \"call_YBUn0S5ErhjkfnjFbWWJYIvR\",\n \"type\": - \"function\",\n \"function\": {\n \"name\": \"get_current_weather\",\n - \ \"arguments\": \"{\\\"location\\\": \\\"Seattle, WA\\\"}\"\n - \ }\n },\n {\n \"id\": \"call_Ail5xuGFVRk2wUPidQWDYytn\",\n - \ \"type\": \"function\",\n \"function\": {\n \"name\": - \"get_current_weather\",\n \"arguments\": \"{\\\"location\\\": - \\\"San Francisco, CA\\\"}\"\n }\n }\n ],\n \"refusal\": - null\n },\n \"logprobs\": null,\n \"finish_reason\": \"tool_calls\"\n - \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 75,\n \"completion_tokens\": - 51,\n \"total_tokens\": 126,\n \"prompt_tokens_details\": {\n \"cached_tokens\": - 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": - 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + string: |- + { + "id": "chatcmpl-APfFOuWLsYvVpZYqENRo9rKnifNdD", + "object": "chat.completion", + "created": 1730680118, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_6YvurIMPOgMo2q6V6KGJDA6g", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_QSiqEulo25M3NtTLVbMGqY91", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d87e6e7ba75dee2-SEA + - 8dd07c349cb38bcb-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Sat, 26 Oct 2024 05:03:49 GMT + - Mon, 04 Nov 2024 00:28:39 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -85,38 +145,74 @@ interactions: - '1180' openai-organization: test_organization openai-processing-ms: - - '649' + - '631' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '198' + - '9996' x-ratelimit-remaining-tokens: - - '59961' + - '199961' x-ratelimit-reset-requests: - - 14m23.304s + - 29.791s x-ratelimit-reset-tokens: - - 39ms + - 11ms x-request-id: - - req_b2f085c19f19c32c8aa891887e228402 + - req_a121f023915b3c4a2ca2415663e54dd8 status: code: 200 message: OK - request: - body: '{"messages": [{"role": "system", "content": "You''re a helpful assistant."}, - {"role": "user", "content": "What''s the weather in Seattle and San Francisco - today?"}, {"role": "assistant", "tool_calls": [{"id": "call_YBUn0S5ErhjkfnjFbWWJYIvR", - "function": {"arguments": "{\"location\": \"Seattle, WA\"}", "name": "get_current_weather"}, - "type": "function"}, {"id": "call_Ail5xuGFVRk2wUPidQWDYytn", "function": {"arguments": - "{\"location\": \"San Francisco, CA\"}", "name": "get_current_weather"}, "type": - "function"}]}, {"role": "tool", "content": "50 degrees and raining", "tool_call_id": - "call_YBUn0S5ErhjkfnjFbWWJYIvR"}, {"role": "tool", "content": "70 degrees and - sunny", "tool_call_id": "call_Ail5xuGFVRk2wUPidQWDYytn"}], "model": "gpt-4o-mini"}' + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_6YvurIMPOgMo2q6V6KGJDA6g", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_QSiqEulo25M3NtTLVbMGqY91", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_6YvurIMPOgMo2q6V6KGJDA6g" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_QSiqEulo25M3NtTLVbMGqY91" + } + ], + "model": "gpt-4o-mini" + } headers: accept: - application/json @@ -129,52 +225,72 @@ interactions: content-type: - application/json cookie: - - test_set_cookie + - __cf_bm=Fyf0tyDn1mwa_82CHRs1nppW_PehJkXoYvNM4ZjPbXY-1730680119-1.0.1.1-yjV4_xtp96WEMEexlzeQsjZfgRKwMtgjBU5ysQffHMNwXbTqmZdE_pCTtQTmJ97xP37rkkAHdzC7O8661FKZ9A; + _cfuvid=WLvZI_.UlWSOmjux14bNggQUKClph3WCDG.6pjaRbjI-1730680119424-0.0.1.1-604800000 host: - api.openai.com user-agent: - - OpenAI/Python 1.52.2 + - OpenAI/Python 1.26.0 x-stainless-arch: - - other:amd64 + - arm64 x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - Windows + - MacOS x-stainless-package-version: - - 1.52.2 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AMTFlFwfqawbaH57GE3mXL8O17xo1\",\n \"object\": - \"chat.completion\",\n \"created\": 1729919029,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"Today, the weather in Seattle is 50 - degrees and raining, while in San Francisco, it is 70 degrees and sunny.\",\n - \ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": - \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 99,\n \"completion_tokens\": - 26,\n \"total_tokens\": 125,\n \"prompt_tokens_details\": {\n \"cached_tokens\": - 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": - 0\n }\n },\n \"system_fingerprint\": \"fp_f59a81427f\"\n}\n" + string: |- + { + "id": "chatcmpl-APfFP2ZYRsgIvw0HuTVbYFDxFs7Si", + "object": "chat.completion", + "created": 1730680119, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 25, + "total_tokens": 124, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8d87e6ec8ddedee2-SEA + - 8dd07c3ad9138bcb-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Sat, 26 Oct 2024 05:03:49 GMT + - Mon, 04 Nov 2024 00:28:40 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -187,28 +303,28 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '732' + - '731' openai-organization: test_organization openai-processing-ms: - - '537' + - '390' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '200' + - '10000' x-ratelimit-limit-tokens: - - '60000' + - '200000' x-ratelimit-remaining-requests: - - '197' + - '9995' x-ratelimit-remaining-tokens: - - '59948' + - '199947' x-ratelimit-reset-requests: - - 21m34.534s + - 37.448s x-ratelimit-reset-tokens: - - 52ms + - 15ms x-request-id: - - req_ca78782b171f5cd60841ba443de92731 + - req_525d3b9301fff00a98647143a9c26b6f status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml index 3bfd94e415..bb61c001fb 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -1,7 +1,16 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Say this is a test"}], "model": - "gpt-4", "stream": false}' + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } headers: accept: - application/json @@ -10,13 +19,13 @@ interactions: connection: - keep-alive content-length: - - '100' + - '106' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.47.0 + - OpenAI/Python 1.26.0 x-stainless-arch: - arm64 x-stainless-async: @@ -26,34 +35,57 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.47.0 + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.11.5 + - 3.12.6 method: POST uri: https://api.openai.com/v1/chat/completions response: body: - string: "{\n \"id\": \"chatcmpl-AC6ajKKHHpvf6x2Qm35t6m3QE8qli\",\n \"object\": - \"chat.completion\",\n \"created\": 1727448637,\n \"model\": \"gpt-4-0613\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"This is a test.\",\n \"refusal\": - null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n - \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 12,\n \"completion_tokens\": - 5,\n \"total_tokens\": 17,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": - 0\n }\n },\n \"system_fingerprint\": null\n}\n" + string: |- + { + "id": "chatcmpl-APfFJNBzCZVUpMJMK5KBhu4D6yVAc", + "object": "chat.completion", + "created": 1730680113, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test! How can I assist you today?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8c9c4e9b7fb674d8-PMO + - 8dd07c16eae44a1d-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Fri, 27 Sep 2024 14:50:37 GMT + - Mon, 04 Nov 2024 00:28:34 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -63,11 +95,13 @@ interactions: - nosniff access-control-expose-headers: - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 content-length: - - '551' + - '666' openai-organization: test_organization openai-processing-ms: - - '434' + - '732' openai-version: - '2020-10-01' strict-transport-security: @@ -75,17 +109,17 @@ interactions: x-ratelimit-limit-requests: - '10000' x-ratelimit-limit-tokens: - - '1000000' + - '200000' x-ratelimit-remaining-requests: - '9999' x-ratelimit-remaining-tokens: - - '999977' + - '199977' x-ratelimit-reset-requests: - - 6ms + - 8.64s x-ratelimit-reset-tokens: - - 1ms + - 6ms x-request-id: - - req_5f2690abaf909a9f047488694d44495e + - req_0bb3c9da7d953e477d1947130d2cf1df status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index f35dfbacf2..84a9bf2692 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -1,8 +1,10 @@ """Unit tests configuration module.""" +import json import os import pytest +import yaml from openai import OpenAI from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor @@ -98,6 +100,73 @@ def instrument_with_content(tracer_provider, event_logger_provider): instrumentor.uninstrument() +class LiteralBlockScalar(str): + """Formats the string as a literal block scalar, preserving whitespace and + without interpreting escape characters""" + + +def literal_block_scalar_presenter(dumper, data): + """Represents a scalar string as a literal block, via '|' syntax""" + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|") + + +yaml.add_representer(LiteralBlockScalar, literal_block_scalar_presenter) + + +def process_string_value(string_value): + """Pretty-prints JSON or returns long strings as a LiteralBlockScalar""" + try: + json_data = json.loads(string_value) + return LiteralBlockScalar(json.dumps(json_data, indent=2)) + except (ValueError, TypeError): + if len(string_value) > 80: + return LiteralBlockScalar(string_value) + return string_value + + +def convert_body_to_literal(data): + """Searches the data for body strings, attempting to pretty-print JSON""" + if isinstance(data, dict): + for key, value in data.items(): + # Handle response body case (e.g., response.body.string) + if key == "body" and isinstance(value, dict) and "string" in value: + value["string"] = process_string_value(value["string"]) + + # Handle request body case (e.g., request.body) + elif key == "body" and isinstance(value, str): + data[key] = process_string_value(value) + + else: + convert_body_to_literal(value) + + elif isinstance(data, list): + for idx, choice in enumerate(data): + data[idx] = convert_body_to_literal(choice) + + return data + + +class PrettyPrintJSONBody: + """This makes request and response body recordings more readable.""" + + @staticmethod + def serialize(cassette_dict): + cassette_dict = convert_body_to_literal(cassette_dict) + return yaml.dump( + cassette_dict, default_flow_style=False, allow_unicode=True + ) + + @staticmethod + def deserialize(cassette_string): + return yaml.load(cassette_string, Loader=yaml.Loader) + + +@pytest.fixture(scope="module") +def fixture_vcr(vcr): + vcr.register_serializer("yaml", PrettyPrintJSONBody) + return vcr + + def scrub_response_headers(response): """ This scrubs sensitive response headers. Note they are case-sensitive! diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index 4369aa6a38..c6cb19aa8d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -16,7 +16,7 @@ from typing import Optional import pytest -from openai import OpenAI +from openai import APIConnectionError, NotFoundError, OpenAI from openai.resources.chat.completions import ChatCompletion from opentelemetry.sdk.trace import ReadableSpan @@ -73,16 +73,12 @@ def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): client = OpenAI(base_url="http://localhost:4242") - exception = None - try: + with pytest.raises(APIConnectionError): client.chat.completions.create( messages=messages_value, model=llm_model_value, timeout=0.1, ) - assert False, "Expected an exception" - except Exception as ex: # pylint: disable=broad-exception-caught - exception = ex spans = span_exporter.get_finished_spans() assert_all_attributes( @@ -90,8 +86,7 @@ def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): ) assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] assert ( - type(exception).__qualname__ - == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] ) @@ -102,24 +97,16 @@ def test_chat_completion_404( llm_model_value = "this-model-does-not-exist" messages_value = [{"role": "user", "content": "Say this is a test"}] - exception = None - try: + with pytest.raises(NotFoundError): openai_client.chat.completions.create( messages=messages_value, model=llm_model_value, - timeout=0.1, ) - assert False, "Expected an exception" - except Exception as ex: # pylint: disable=broad-exception-caught - exception = ex spans = span_exporter.get_finished_spans() assert_all_attributes(spans[0], llm_model_value) - assert ( - type(exception).__qualname__ - == spans[0].attributes[ErrorAttributes.ERROR_TYPE] - ) + assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] @pytest.mark.vcr() From 8cfbca2293f34c5c56db8d51db366bd007dde280 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 5 Nov 2024 09:39:29 +0100 Subject: [PATCH 214/335] opentelemetry-instrumentation-system-metrics: don't report open file descriptors on windows (#2946) * opentelemetry-instrumentation-system-metrics: don't report files descriptors on windows * Run manually added tox env tests on windows too * Add jobs for botocore and system-metrics on windows * Skip open file descriptor test on windows --------- Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> --- .github/workflows/generate_workflows.py | 4 +- .../src/generate_workflows_lib/__init__.py | 16 +++++++ .github/workflows/test_1.yml | 42 +++++++++++++++++++ CHANGELOG.md | 2 + .../system_metrics/__init__.py | 5 ++- .../tests/test_system_metrics.py | 17 ++++++-- 6 files changed, 81 insertions(+), 5 deletions(-) diff --git a/.github/workflows/generate_workflows.py b/.github/workflows/generate_workflows.py index bda8eee827..ce6b56abe6 100644 --- a/.github/workflows/generate_workflows.py +++ b/.github/workflows/generate_workflows.py @@ -9,6 +9,8 @@ tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") workflows_directory_path = Path(__file__).parent -generate_test_workflow(tox_ini_path, workflows_directory_path, "ubuntu-latest") +generate_test_workflow( + tox_ini_path, workflows_directory_path, "ubuntu-latest", "windows-latest" +) generate_lint_workflow(tox_ini_path, workflows_directory_path) generate_misc_workflow(tox_ini_path, workflows_directory_path) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index 0308fbe5f3..d0889abc48 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -55,6 +55,14 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: "py312": "3.12", } + # we enable windows testing only for packages with windows specific code paths + per_tox_env_os_enablement = { + "windows-latest": { + "py312-test-instrumentation-botocore", + "py312-test-instrumentation-system-metrics", + }, + } + test_job_datas = [] for operating_system in operating_systems: @@ -71,6 +79,14 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: ] tox_env = tox_test_env_match.string + # if we have an entry for the os add only jobs for tox env manually configured + packages_manually_enabled = per_tox_env_os_enablement.get( + operating_system + ) + if packages_manually_enabled: + if tox_env not in packages_manually_enabled: + continue + test_requirements = groups["test_requirements"] if test_requirements is None: diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 30e02c5634..2615280e4c 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -3903,3 +3903,45 @@ jobs: - name: Run tests run: tox -e pypy3-test-processor-baggage -- -ra + + py312-test-instrumentation-botocore_windows-latest: + name: instrumentation-botocore 3.12 Windows + runs-on: windows-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Configure git to support long filenames + run: git config --system core.longpaths true + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore -- -ra + + py312-test-instrumentation-system-metrics_windows-latest: + name: instrumentation-system-metrics 3.12 Windows + runs-on: windows-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Configure git to support long filenames + run: git config --system core.longpaths true + + - name: Run tests + run: tox -e py312-test-instrumentation-system-metrics -- -ra diff --git a/CHANGELOG.md b/CHANGELOG.md index 47191002dc..04498c8639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2940](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2940)) - `opentelemetry-instrumentation-dbapi` sqlcommenter key values created from PostgreSQL, MySQL systems ([#2897](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2897)) +- `opentelemetry-instrumentation-system-metrics`: don't report open file descriptors on Windows + ([#2946](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2946)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index 0953e65fb5..4e1ee2a5df 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -397,7 +397,10 @@ def _instrument(self, **kwargs): unit="switches", ) - if "process.open_file_descriptor.count" in self._config: + if ( + sys.platform != "win32" + and "process.open_file_descriptor.count" in self._config + ): self._meter.create_observable_up_down_counter( name="process.open_file_descriptor.count", callbacks=[self._get_open_file_descriptors], diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py index bf3a5c6ee2..83abcff4c0 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py @@ -14,6 +14,7 @@ # pylint: disable=protected-access +import sys from collections import namedtuple from platform import python_implementation from unittest import mock, skipIf @@ -118,21 +119,30 @@ def test_system_metrics_instrument(self): f"process.runtime.{self.implementation}.thread_count", f"process.runtime.{self.implementation}.context_switches", f"process.runtime.{self.implementation}.cpu.utilization", - "process.open_file_descriptor.count", ] + on_windows = sys.platform == "win32" if self.implementation == "pypy": - self.assertEqual(len(metric_names), 21) + self.assertEqual(len(metric_names), 20 if on_windows else 21) else: - self.assertEqual(len(metric_names), 22) + self.assertEqual(len(metric_names), 21 if on_windows else 22) observer_names.append( f"process.runtime.{self.implementation}.gc_count", ) + if not on_windows: + observer_names.append( + "process.open_file_descriptor.count", + ) for observer in metric_names: self.assertIn(observer, observer_names) observer_names.remove(observer) + if on_windows: + self.assertNotIn( + "process.open_file_descriptor.count", observer_names + ) + def test_runtime_metrics_instrument(self): runtime_config = { "process.runtime.memory": ["rss", "vms"], @@ -844,6 +854,7 @@ def test_runtime_cpu_percent(self, mock_process_cpu_percent): f"process.runtime.{self.implementation}.cpu.utilization", expected ) + @skipIf(sys.platform == "win32", "No file descriptors on Windows") @mock.patch("psutil.Process.num_fds") def test_open_file_descriptor_count(self, mock_process_num_fds): mock_process_num_fds.configure_mock(**{"return_value": 3}) From acffef957dbe9e0e4b3057f0c948eed4dc9b529c Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 5 Nov 2024 14:20:03 +0100 Subject: [PATCH 215/335] opentelemetry-instrumentation: stick to latest semantic conventions package (#2952) To match the instrumentations. Will hopefully fix pip not able to handle the situation: opentelemetry-instrumentation 0.49b0 depends on opentelemetry-semantic-conventions>=0.48b0 opentelemetry-instrumentation-dbapi 0.49b0 depends on opentelemetry-semantic-conventions==0.49b0 --- opentelemetry-instrumentation/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index 2bdfd1dbe6..c46a7e8aa7 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.4", - "opentelemetry-semantic-conventions >= 0.48b0", + "opentelemetry-semantic-conventions == 0.49b0.dev", "wrapt >= 1.0.0, < 2.0.0", "packaging >= 18.0", ] From d341ef5062d2f9c73ff87dbca29183385608c3fd Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 5 Nov 2024 12:30:58 -0800 Subject: [PATCH 216/335] prepare before preparing release (#2958) --- .github/workflows/package-prepare-patch-release.yml | 1 + .github/workflows/package-prepare-release.yml | 1 + .github/workflows/package-release.yml | 1 + RELEASING.md | 3 ++- .../src/opentelemetry/instrumentation/openai_v2/version.py | 2 +- 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package-prepare-patch-release.yml b/.github/workflows/package-prepare-patch-release.yml index e9cc7d55ba..a31ce11596 100644 --- a/.github/workflows/package-prepare-patch-release.yml +++ b/.github/workflows/package-prepare-patch-release.yml @@ -8,6 +8,7 @@ on: - opentelemetry-propagator-aws-xray - opentelemetry-resource-detector-azure - opentelemetry-sdk-extension-aws + - opentelemetry-instrumentation-openai-v2 description: 'Package to be released' required: true jobs: diff --git a/.github/workflows/package-prepare-release.yml b/.github/workflows/package-prepare-release.yml index 61dd1eb971..c947741aa0 100644 --- a/.github/workflows/package-prepare-release.yml +++ b/.github/workflows/package-prepare-release.yml @@ -8,6 +8,7 @@ on: - opentelemetry-propagator-aws-xray - opentelemetry-resource-detector-azure - opentelemetry-sdk-extension-aws + - opentelemetry-instrumentation-openai-v2 description: 'Package to be released' required: true diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index 823f2c83d2..01c598f7f1 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -8,6 +8,7 @@ on: - opentelemetry-propagator-aws-xray - opentelemetry-resource-detector-azure - opentelemetry-sdk-extension-aws + - opentelemetry-instrumentation-openai-v2 description: 'Package to be released' required: true jobs: diff --git a/RELEASING.md b/RELEASING.md index c1c923b705..2706d36c8f 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -19,7 +19,7 @@ > - opentelemetry-propagator-aws-xray > - opentelemetry-resource-detector-azure > - opentelemetry-sdk-extension-aws -> +> - opentelemetry-instrumentation-openai-v2 > These libraries are also excluded from the general release. Package release preparation is handled by the [`[Package] Prepare release`](./.github/workflows/package-prepare-release.yml) workflow that allows @@ -70,6 +70,7 @@ The workflow can only be run against long-term release branch such as `package-r > - opentelemetry-propagator-aws-xray > - opentelemetry-resource-detector-azure > - opentelemetry-sdk-extension-aws +> - opentelemetry-instrumentation-openai-v2 > > These libraries are also excluded from the general patch release. diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py index 0e95b73df6..61ae9b7c25 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.0.0.dev" +__version__ = "2.0b0.dev" From 6c88f01f0cc38e30cf6c889428fd6f73927507d7 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:28:54 -0600 Subject: [PATCH 217/335] Update opentelemetry-instrumentation-openai-v2 version to v2.1b0 (#2960) --- .../opentelemetry-instrumentation-openai-v2/CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/openai_v2/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 16ecbdaefe..adac1168c4 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 2.0b0 (2024-11-05) + - Use generic `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` environment variable to control if content of prompt, completion, and other messages is captured. ([#2947](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2947)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py index 61ae9b7c25..5b77207d9d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.0b0.dev" +__version__ = "2.1b0.dev" From 226258e45757f1ecb046dc496b7e2e363cf2dddf Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:22:03 -0600 Subject: [PATCH 218/335] Update version to 1.29.0.dev/0.50b0.dev (#2954) --- .../src/generate_workflows_lib/misc.yml.j2 | 6 +- .github/workflows/lint_0.yml | 2 +- .github/workflows/misc_0.yml | 6 +- .github/workflows/test_0.yml | 2 +- .github/workflows/test_1.yml | 2 +- CHANGELOG.md | 2 + _template/version.py | 2 +- eachdist.ini | 4 +- .../prometheus_remote_write/version.py | 2 +- .../pyproject.toml | 2 +- .../exporter/richconsole/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/aio_pika/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_client/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_server/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiokafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiopg/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asgi/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncio/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncpg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aws_lambda/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto3sqs/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/botocore/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/cassandra/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/celery/version.py | 2 +- .../pyproject.toml | 2 +- .../confluent_kafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/dbapi/version.py | 2 +- .../pyproject.toml | 10 +- .../instrumentation/django/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/elasticsearch/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/falcon/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/fastapi/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/flask/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/grpc/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/httpx/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/jinja2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/kafka/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/logging/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysqlclient/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymemcache/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymongo/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymysql/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/pyramid/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/redis/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/remoulade/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/requests/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlalchemy/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlite3/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/starlette/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/system_metrics/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/threading/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/tornado/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/tortoiseorm/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib3/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/wsgi/version.py | 2 +- .../pyproject.toml | 96 ++++++++--------- .../contrib-instrumentations/version.py | 2 +- opentelemetry-distro/pyproject.toml | 4 +- .../src/opentelemetry/distro/version.py | 2 +- opentelemetry-instrumentation/pyproject.toml | 2 +- .../instrumentation/bootstrap_gen.py | 100 +++++++++--------- .../opentelemetry/instrumentation/version.py | 2 +- .../processor/baggage/version.py | 2 +- .../propagators/ot_trace/version.py | 2 +- .../resource/detector/container/version.py | 2 +- .../src/opentelemetry/util/http/version.py | 2 +- 118 files changed, 287 insertions(+), 279 deletions(-) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index a3fdadf7a3..add97c645a 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -23,13 +23,17 @@ jobs: {%- if job_data == "generate-workflows" %} if: | !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') - && github.actor != 'opentelemetrybot' && github.event_name == 'pull_request' + && github.event.pull_request.user.login != 'opentelemetrybot' && github.event_name == 'pull_request' {%- endif %} {%- if job_data == "public-symbols-check" %} if: | !contains(github.event.pull_request.labels.*.name, 'Approve Public API check') && github.actor != 'opentelemetrybot' && github.event_name == 'pull_request' {%- endif %} + {%- if job_data == "docs" %} + if: | + github.event.pull_request.user.login != 'opentelemetrybot' && github.event_name == 'pull_request' + {%- endif %} steps: - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} uses: actions/checkout@v4 diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index 1fd3198785..dcdee00423 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index e367048b72..99fee8a41b 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w @@ -55,6 +55,8 @@ jobs: docs: name: docs runs-on: ubuntu-latest + if: | + github.event.pull_request.user.login != 'opentelemetrybot' && github.event_name == 'pull_request' steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 @@ -96,7 +98,7 @@ jobs: runs-on: ubuntu-latest if: | !contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows') - && github.actor != 'opentelemetrybot' && github.event_name == 'pull_request' + && github.event.pull_request.user.login != 'opentelemetrybot' && github.event_name == 'pull_request' steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index df74e90021..c68bc9316c 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 2615280e4c..c58b33909f 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: main + CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/CHANGELOG.md b/CHANGELOG.md index 04498c8639..d0794f81a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 1.28.0/0.49b0 (2024-11-05) + ### Added - `opentelemetry-instrumentation-openai-v2` Instrumentation for OpenAI >= 0.27.0 diff --git a/_template/version.py b/_template/version.py index ee5a6342e7..0559ba6227 100644 --- a/_template/version.py +++ b/_template/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/eachdist.ini b/eachdist.ini index c04fb571ce..e27258fe65 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -16,7 +16,7 @@ sortfirst= ext/* [stable] -version=1.28.0.dev +version=1.29.0.dev packages= opentelemetry-sdk @@ -34,7 +34,7 @@ packages= opentelemetry-api [prerelease] -version=0.49b0.dev +version=0.50b0.dev packages= all diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py index ee5a6342e7..0559ba6227 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index eb00eb0437..03a38a8647 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-sdk ~= 1.12", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "rich>=10.0.0", ] diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py index ee5a6342e7..0559ba6227 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 65dfe3c7ac..c6dff9b9bd 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index fbe663a50b..f6f4263ec6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py index 49b83ce95e..192d972f78 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index a8e912e68d..86df1fc38e 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index b2c72bc397..4398f686c8 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.27", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 3a583db3dd..5236344665 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 45c436aad4..eef272575a 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ dependencies = [ "asgiref ~= 3.0", "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index 36ed960392..b7e1287c72 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.14", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 5a6632a028..b5ba5d6ad2 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index 6c1aad7d23..bc5c7c4426 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index a2bdba302f..68628c427a 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 72dc38cbec..172642033d 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index dae5b29661..3e4618844f 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 3e785d1e8b..98b1121db4 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 9f0f594581..4c88789714 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 2edfdeb038..5c9436513f 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "opentelemetry-api ~= 1.12", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index bfa63dbcad..da1b043672 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py index 79e27849a4..d7d982fafc 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index 27cdf157c4..6b0204ef81 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -26,15 +26,15 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-wsgi == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-wsgi == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] asgi = [ - "opentelemetry-instrumentation-asgi == 0.49b0.dev", + "opentelemetry-instrumentation-asgi == 0.50b0.dev", ] instruments = [ "django >= 1.10", diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index e086d2c335..32dcb1ad7e 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index f118ff4296..dd30ee6ba2 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-wsgi == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-wsgi == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "packaging >= 20.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 89f6602e86..9f64ab1ca4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-asgi == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-asgi == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 8d02775824..d5a27c78e7 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-wsgi == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-wsgi == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "packaging >= 21.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index fd84d6aac0..18cb2d3f0e 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index c986fac4a1..e4479223a4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index 40159c3485..57f689a961 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index d47672fa07..d5dc500101 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 62656bea22..2bb377f5ef 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py index 79e27849a4..d7d982fafc 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 629ab5325e..41273b0e22 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index 0cc4553384..4edcbb08b1 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index bc01323ee4..4c32c12e82 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", "wrapt >= 1.0.0, < 2.0.0", diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 513064ae7f..22af126330 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 592c15b4db..daf8c8efd4 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index c20ffd3dee..0e1fa1a47f 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index 61f4fd2b72..c9204d71b9 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 9e1bc1a881..fe68be60ab 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 2a559e6c60..585a52c879 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-wsgi == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-wsgi == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index c262363fab..c46d97aa9a 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.12.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 7f3041b887..b7ff83f4db 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index dafe3b4d3a..7dab991cbc 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index d6cc3f71d9..f8ce651b6c 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "packaging >= 21.0", "wrapt >= 1.11.2", ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index 60ec47b16e..d089fc27e9 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-dbapi == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-dbapi == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py index 79e27849a4..d7d982fafc 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 9cdd968ca0..13c4cc0fc2 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-instrumentation-asgi == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation-asgi == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index a405c668f7..3808b4ec0f 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "opentelemetry-api ~= 1.11", "psutil >= 5.9.0, < 7", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 43f92d2034..7f18ae7b40 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index f3f9a4b4fc..eaeb69324f 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 82ccbc6a79..f53e19018c 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 97b611b095..d7a98924aa 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index 79e27849a4..d7d982fafc 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 3c1eaaa6d0..b1cf28d8ff 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index a5e81ee8e5..dddb4a4eb1 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", - "opentelemetry-semantic-conventions == 0.49b0.dev", - "opentelemetry-util-http == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-util-http == 0.50b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py index ee5a6342e7..0559ba6227 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index b34226b669..29a3d51a96 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -29,55 +29,55 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation-aio-pika==0.49b0.dev", - "opentelemetry-instrumentation-aiohttp-client==0.49b0.dev", - "opentelemetry-instrumentation-aiohttp-server==0.49b0.dev", - "opentelemetry-instrumentation-aiokafka==0.49b0.dev", - "opentelemetry-instrumentation-aiopg==0.49b0.dev", - "opentelemetry-instrumentation-asgi==0.49b0.dev", - "opentelemetry-instrumentation-asyncio==0.49b0.dev", - "opentelemetry-instrumentation-asyncpg==0.49b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.49b0.dev", - "opentelemetry-instrumentation-boto==0.49b0.dev", - "opentelemetry-instrumentation-boto3sqs==0.49b0.dev", - "opentelemetry-instrumentation-botocore==0.49b0.dev", - "opentelemetry-instrumentation-cassandra==0.49b0.dev", - "opentelemetry-instrumentation-celery==0.49b0.dev", - "opentelemetry-instrumentation-confluent-kafka==0.49b0.dev", - "opentelemetry-instrumentation-dbapi==0.49b0.dev", - "opentelemetry-instrumentation-django==0.49b0.dev", - "opentelemetry-instrumentation-elasticsearch==0.49b0.dev", - "opentelemetry-instrumentation-falcon==0.49b0.dev", - "opentelemetry-instrumentation-fastapi==0.49b0.dev", - "opentelemetry-instrumentation-flask==0.49b0.dev", - "opentelemetry-instrumentation-grpc==0.49b0.dev", - "opentelemetry-instrumentation-httpx==0.49b0.dev", - "opentelemetry-instrumentation-jinja2==0.49b0.dev", - "opentelemetry-instrumentation-kafka-python==0.49b0.dev", - "opentelemetry-instrumentation-logging==0.49b0.dev", - "opentelemetry-instrumentation-mysql==0.49b0.dev", - "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", - "opentelemetry-instrumentation-pika==0.49b0.dev", - "opentelemetry-instrumentation-psycopg==0.49b0.dev", - "opentelemetry-instrumentation-psycopg2==0.49b0.dev", - "opentelemetry-instrumentation-pymemcache==0.49b0.dev", - "opentelemetry-instrumentation-pymongo==0.49b0.dev", - "opentelemetry-instrumentation-pymysql==0.49b0.dev", - "opentelemetry-instrumentation-pyramid==0.49b0.dev", - "opentelemetry-instrumentation-redis==0.49b0.dev", - "opentelemetry-instrumentation-remoulade==0.49b0.dev", - "opentelemetry-instrumentation-requests==0.49b0.dev", - "opentelemetry-instrumentation-sqlalchemy==0.49b0.dev", - "opentelemetry-instrumentation-sqlite3==0.49b0.dev", - "opentelemetry-instrumentation-starlette==0.49b0.dev", - "opentelemetry-instrumentation-system-metrics==0.49b0.dev", + "opentelemetry-instrumentation-aio-pika==0.50b0.dev", + "opentelemetry-instrumentation-aiohttp-client==0.50b0.dev", + "opentelemetry-instrumentation-aiohttp-server==0.50b0.dev", + "opentelemetry-instrumentation-aiokafka==0.50b0.dev", + "opentelemetry-instrumentation-aiopg==0.50b0.dev", + "opentelemetry-instrumentation-asgi==0.50b0.dev", + "opentelemetry-instrumentation-asyncio==0.50b0.dev", + "opentelemetry-instrumentation-asyncpg==0.50b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.50b0.dev", + "opentelemetry-instrumentation-boto==0.50b0.dev", + "opentelemetry-instrumentation-boto3sqs==0.50b0.dev", + "opentelemetry-instrumentation-botocore==0.50b0.dev", + "opentelemetry-instrumentation-cassandra==0.50b0.dev", + "opentelemetry-instrumentation-celery==0.50b0.dev", + "opentelemetry-instrumentation-confluent-kafka==0.50b0.dev", + "opentelemetry-instrumentation-dbapi==0.50b0.dev", + "opentelemetry-instrumentation-django==0.50b0.dev", + "opentelemetry-instrumentation-elasticsearch==0.50b0.dev", + "opentelemetry-instrumentation-falcon==0.50b0.dev", + "opentelemetry-instrumentation-fastapi==0.50b0.dev", + "opentelemetry-instrumentation-flask==0.50b0.dev", + "opentelemetry-instrumentation-grpc==0.50b0.dev", + "opentelemetry-instrumentation-httpx==0.50b0.dev", + "opentelemetry-instrumentation-jinja2==0.50b0.dev", + "opentelemetry-instrumentation-kafka-python==0.50b0.dev", + "opentelemetry-instrumentation-logging==0.50b0.dev", + "opentelemetry-instrumentation-mysql==0.50b0.dev", + "opentelemetry-instrumentation-mysqlclient==0.50b0.dev", + "opentelemetry-instrumentation-pika==0.50b0.dev", + "opentelemetry-instrumentation-psycopg==0.50b0.dev", + "opentelemetry-instrumentation-psycopg2==0.50b0.dev", + "opentelemetry-instrumentation-pymemcache==0.50b0.dev", + "opentelemetry-instrumentation-pymongo==0.50b0.dev", + "opentelemetry-instrumentation-pymysql==0.50b0.dev", + "opentelemetry-instrumentation-pyramid==0.50b0.dev", + "opentelemetry-instrumentation-redis==0.50b0.dev", + "opentelemetry-instrumentation-remoulade==0.50b0.dev", + "opentelemetry-instrumentation-requests==0.50b0.dev", + "opentelemetry-instrumentation-sqlalchemy==0.50b0.dev", + "opentelemetry-instrumentation-sqlite3==0.50b0.dev", + "opentelemetry-instrumentation-starlette==0.50b0.dev", + "opentelemetry-instrumentation-system-metrics==0.50b0.dev", "opentelemetry-instrumentation-test==1.0.0b.dev", - "opentelemetry-instrumentation-threading==0.49b0.dev", - "opentelemetry-instrumentation-tornado==0.49b0.dev", - "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", - "opentelemetry-instrumentation-urllib==0.49b0.dev", - "opentelemetry-instrumentation-urllib3==0.49b0.dev", - "opentelemetry-instrumentation-wsgi==0.49b0.dev", + "opentelemetry-instrumentation-threading==0.50b0.dev", + "opentelemetry-instrumentation-tornado==0.50b0.dev", + "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", + "opentelemetry-instrumentation-urllib==0.50b0.dev", + "opentelemetry-instrumentation-urllib3==0.50b0.dev", + "opentelemetry-instrumentation-wsgi==0.50b0.dev", ] [project.urls] diff --git a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py index ee5a6342e7..0559ba6227 100644 --- a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py +++ b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 686eeaba95..dd995f2f99 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -27,13 +27,13 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.49b0.dev", + "opentelemetry-instrumentation == 0.50b0.dev", "opentelemetry-sdk ~= 1.13", ] [project.optional-dependencies] otlp = [ - "opentelemetry-exporter-otlp == 1.28.0.dev", + "opentelemetry-exporter-otlp == 1.29.0.dev", ] [project.entry-points.opentelemetry_configurator] diff --git a/opentelemetry-distro/src/opentelemetry/distro/version.py b/opentelemetry-distro/src/opentelemetry/distro/version.py index ee5a6342e7..0559ba6227 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/version.py +++ b/opentelemetry-distro/src/opentelemetry/distro/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index c46a7e8aa7..f8aad72f4a 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.4", - "opentelemetry-semantic-conventions == 0.49b0.dev", + "opentelemetry-semantic-conventions == 0.50b0.dev", "wrapt >= 1.0.0, < 2.0.0", "packaging >= 18.0", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index ff6065d058..8192b1fff9 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -18,184 +18,184 @@ libraries = [ { "library": "aio_pika >= 7.2.0, < 10.0.0", - "instrumentation": "opentelemetry-instrumentation-aio-pika==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-aio-pika==0.50b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.50b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.50b0.dev", }, { "library": "aiokafka >= 0.8, < 1.0", - "instrumentation": "opentelemetry-instrumentation-aiokafka==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiokafka==0.50b0.dev", }, { "library": "aiopg >= 0.13.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiopg==0.50b0.dev", }, { "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-asgi==0.50b0.dev", }, { "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncpg==0.50b0.dev", }, { "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto==0.50b0.dev", }, { "library": "boto3 ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.50b0.dev", }, { "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.50b0.dev", }, { "library": "cassandra-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.50b0.dev", }, { "library": "scylla-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.50b0.dev", }, { "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-celery==0.50b0.dev", }, { "library": "confluent-kafka >= 1.8.2, <= 2.4.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.50b0.dev", }, { "library": "django >= 1.10", - "instrumentation": "opentelemetry-instrumentation-django==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-django==0.50b0.dev", }, { "library": "elasticsearch >= 6.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.50b0.dev", }, { "library": "falcon >= 1.4.1, < 3.1.2", - "instrumentation": "opentelemetry-instrumentation-falcon==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-falcon==0.50b0.dev", }, { "library": "fastapi ~= 0.58", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.50b0.dev", }, { "library": "flask >= 1.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-flask==0.50b0.dev", }, { "library": "grpcio >= 1.42.0", - "instrumentation": "opentelemetry-instrumentation-grpc==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-grpc==0.50b0.dev", }, { "library": "httpx >= 0.18.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-httpx==0.50b0.dev", }, { "library": "jinja2 >= 2.7, < 4.0", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-jinja2==0.50b0.dev", }, { "library": "kafka-python >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.50b0.dev", }, { "library": "kafka-python-ng >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.50b0.dev", }, { "library": "mysql-connector-python >= 8.0, < 10.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysql==0.50b0.dev", }, { "library": "mysqlclient < 3", - "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.50b0.dev", }, { "library": "pika >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-pika==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-pika==0.50b0.dev", }, { "library": "psycopg >= 3.1.0", - "instrumentation": "opentelemetry-instrumentation-psycopg==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg==0.50b0.dev", }, { "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.50b0.dev", }, { "library": "pymemcache >= 1.3.5, < 5", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymemcache==0.50b0.dev", }, { "library": "pymongo >= 3.1, < 5.0", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymongo==0.50b0.dev", }, { "library": "PyMySQL < 2", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymysql==0.50b0.dev", }, { "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-pyramid==0.50b0.dev", }, { "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-redis==0.50b0.dev", }, { "library": "remoulade >= 0.50", - "instrumentation": "opentelemetry-instrumentation-remoulade==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-remoulade==0.50b0.dev", }, { "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-requests==0.50b0.dev", }, { "library": "sqlalchemy", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.50b0.dev", }, { "library": "starlette ~= 0.13.0", - "instrumentation": "opentelemetry-instrumentation-starlette==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-starlette==0.50b0.dev", }, { "library": "psutil >= 5", - "instrumentation": "opentelemetry-instrumentation-system-metrics==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-system-metrics==0.50b0.dev", }, { "library": "tornado >= 5.1.1", - "instrumentation": "opentelemetry-instrumentation-tornado==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-tornado==0.50b0.dev", }, { "library": "tortoise-orm >= 0.17.0", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", }, { "library": "pydantic >= 1.10.2", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", }, { "library": "urllib3 >= 1.0.0, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.49b0.dev", + "instrumentation": "opentelemetry-instrumentation-urllib3==0.50b0.dev", }, ] default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.49b0.dev", - "opentelemetry-instrumentation-dbapi==0.49b0.dev", - "opentelemetry-instrumentation-logging==0.49b0.dev", - "opentelemetry-instrumentation-sqlite3==0.49b0.dev", + "opentelemetry-instrumentation-asyncio==0.50b0.dev", + "opentelemetry-instrumentation-dbapi==0.50b0.dev", + "opentelemetry-instrumentation-logging==0.50b0.dev", + "opentelemetry-instrumentation-sqlite3==0.50b0.dev", "opentelemetry-instrumentation-test==1.0.0b.dev", - "opentelemetry-instrumentation-threading==0.49b0.dev", - "opentelemetry-instrumentation-urllib==0.49b0.dev", - "opentelemetry-instrumentation-wsgi==0.49b0.dev", + "opentelemetry-instrumentation-threading==0.50b0.dev", + "opentelemetry-instrumentation-urllib==0.50b0.dev", + "opentelemetry-instrumentation-wsgi==0.50b0.dev", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index ee5a6342e7..0559ba6227 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py index ee5a6342e7..0559ba6227 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py index ee5a6342e7..0559ba6227 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py index ee5a6342e7..0559ba6227 100644 --- a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py +++ b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py index ee5a6342e7..0559ba6227 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.49b0.dev" +__version__ = "0.50b0.dev" From 77613da39651e9406f163249c5cc90e6e226d964 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 6 Nov 2024 17:36:33 +0100 Subject: [PATCH 219/335] Drop selective enabled for windows and regenerate workflows (#2964) --- .github/workflows/generate_workflows.py | 4 +- .../src/generate_workflows_lib/__init__.py | 16 ------- .github/workflows/lint_0.yml | 2 +- .github/workflows/misc_0.yml | 2 +- .github/workflows/test_0.yml | 2 +- .github/workflows/test_1.yml | 44 +------------------ 6 files changed, 5 insertions(+), 65 deletions(-) diff --git a/.github/workflows/generate_workflows.py b/.github/workflows/generate_workflows.py index ce6b56abe6..bda8eee827 100644 --- a/.github/workflows/generate_workflows.py +++ b/.github/workflows/generate_workflows.py @@ -9,8 +9,6 @@ tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") workflows_directory_path = Path(__file__).parent -generate_test_workflow( - tox_ini_path, workflows_directory_path, "ubuntu-latest", "windows-latest" -) +generate_test_workflow(tox_ini_path, workflows_directory_path, "ubuntu-latest") generate_lint_workflow(tox_ini_path, workflows_directory_path) generate_misc_workflow(tox_ini_path, workflows_directory_path) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index d0889abc48..0308fbe5f3 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -55,14 +55,6 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: "py312": "3.12", } - # we enable windows testing only for packages with windows specific code paths - per_tox_env_os_enablement = { - "windows-latest": { - "py312-test-instrumentation-botocore", - "py312-test-instrumentation-system-metrics", - }, - } - test_job_datas = [] for operating_system in operating_systems: @@ -79,14 +71,6 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: ] tox_env = tox_test_env_match.string - # if we have an entry for the os add only jobs for tox env manually configured - packages_manually_enabled = per_tox_env_os_enablement.get( - operating_system - ) - if packages_manually_enabled: - if tox_env not in packages_manually_enabled: - continue - test_requirements = groups["test_requirements"] if test_requirements is None: diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index dcdee00423..1fd3198785 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 99fee8a41b..ca94a69563 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index c68bc9316c..df74e90021 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index c58b33909f..30e02c5634 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -10,7 +10,7 @@ on: pull_request: env: - CORE_REPO_SHA: 6e29e0e5f19ee08eaf683166f2867dd2d383f67e + CORE_REPO_SHA: main CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w @@ -3903,45 +3903,3 @@ jobs: - name: Run tests run: tox -e pypy3-test-processor-baggage -- -ra - - py312-test-instrumentation-botocore_windows-latest: - name: instrumentation-botocore 3.12 Windows - runs-on: windows-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Configure git to support long filenames - run: git config --system core.longpaths true - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore -- -ra - - py312-test-instrumentation-system-metrics_windows-latest: - name: instrumentation-system-metrics 3.12 Windows - runs-on: windows-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Configure git to support long filenames - run: git config --system core.longpaths true - - - name: Run tests - run: tox -e py312-test-instrumentation-system-metrics -- -ra From 499548ebbb1dd1a32a2a8aa51b24cf7787f68723 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 7 Nov 2024 10:47:19 -0800 Subject: [PATCH 220/335] Test packages that are released individually with lowest versions they support (#2961) --- .github/workflows/test_0.yml | 2180 ++++++++--------- .github/workflows/test_1.yml | 468 +++- .../pyproject.toml | 6 +- .../test-requirements-0.txt | 13 + ...quirements.txt => test-requirements-1.txt} | 1 + .../CHANGELOG.md | 3 + .../pyproject.toml | 2 +- .../test-requirements-0.txt | 21 + ...quirements.txt => test-requirements-1.txt} | 2 + .../CHANGELOG.md | 2 + .../pyproject.toml | 2 +- .../test-requirements-0.txt | 15 + ...quirements.txt => test-requirements-1.txt} | 2 + ...quirements.txt => test-requirements-0.txt} | 2 + .../test-requirements-1.txt | 15 + tox.ini | 81 +- 16 files changed, 1669 insertions(+), 1146 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt rename instrumentation-genai/opentelemetry-instrumentation-openai-v2/{test-requirements.txt => test-requirements-1.txt} (74%) create mode 100644 propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt rename propagator/opentelemetry-propagator-aws-xray/{test-requirements.txt => test-requirements-1.txt} (80%) create mode 100644 resource/opentelemetry-resource-detector-azure/test-requirements-0.txt rename resource/opentelemetry-resource-detector-azure/{test-requirements.txt => test-requirements-1.txt} (74%) rename sdk-extension/opentelemetry-sdk-extension-aws/{test-requirements.txt => test-requirements-0.txt} (77%) create mode 100644 sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index df74e90021..1b8376fdc2 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -16,8 +16,8 @@ env: jobs: - py38-test-instrumentation-openai-v2_ubuntu-latest: - name: instrumentation-openai-v2 3.8 Ubuntu + py38-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -32,190 +32,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-openai-v2 -- -ra + run: tox -e py38-test-instrumentation-openai-v2-0 -- -ra - py39-test-instrumentation-openai-v2_ubuntu-latest: - name: instrumentation-openai-v2 3.9 Ubuntu + py38-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2 -- -ra + run: tox -e py38-test-instrumentation-openai-v2-1 -- -ra - py310-test-instrumentation-openai-v2_ubuntu-latest: - name: instrumentation-openai-v2 3.10 Ubuntu + py39-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-openai-v2 -- -ra + run: tox -e py39-test-instrumentation-openai-v2-0 -- -ra - py311-test-instrumentation-openai-v2_ubuntu-latest: - name: instrumentation-openai-v2 3.11 Ubuntu + py39-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-openai-v2 -- -ra + run: tox -e py39-test-instrumentation-openai-v2-1 -- -ra - py312-test-instrumentation-openai-v2_ubuntu-latest: - name: instrumentation-openai-v2 3.12 Ubuntu + py310-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-openai-v2 -- -ra + run: tox -e py310-test-instrumentation-openai-v2-0 -- -ra - pypy3-test-instrumentation-openai-v2_ubuntu-latest: - name: instrumentation-openai-v2 pypy-3.8 Ubuntu + py310-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-openai-v2 -- -ra + run: tox -e py310-test-instrumentation-openai-v2-1 -- -ra - py38-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 3.8 Ubuntu + py311-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-resource-detector-container -- -ra + run: tox -e py311-test-instrumentation-openai-v2-0 -- -ra - py39-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 3.9 Ubuntu + py311-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-resource-detector-container -- -ra + run: tox -e py311-test-instrumentation-openai-v2-1 -- -ra - py310-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 3.10 Ubuntu + py312-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-resource-detector-container -- -ra + run: tox -e py312-test-instrumentation-openai-v2-0 -- -ra - py311-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 3.11 Ubuntu + py312-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-resource-detector-container -- -ra + run: tox -e py312-test-instrumentation-openai-v2-1 -- -ra - py312-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 3.12 Ubuntu + pypy3-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-resource-detector-container -- -ra + run: tox -e pypy3-test-instrumentation-openai-v2-0 -- -ra - pypy3-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container pypy-3.8 Ubuntu + pypy3-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -230,10 +230,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-resource-detector-container -- -ra + run: tox -e pypy3-test-instrumentation-openai-v2-1 -- -ra - py38-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 3.8 Ubuntu + py38-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -248,10 +248,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-resource-detector-azure -- -ra + run: tox -e py38-test-resource-detector-container -- -ra - py39-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 3.9 Ubuntu + py39-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -266,10 +266,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-resource-detector-azure -- -ra + run: tox -e py39-test-resource-detector-container -- -ra - py310-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 3.10 Ubuntu + py310-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -284,10 +284,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-resource-detector-azure -- -ra + run: tox -e py310-test-resource-detector-container -- -ra - py311-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 3.11 Ubuntu + py311-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -302,10 +302,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-resource-detector-azure -- -ra + run: tox -e py311-test-resource-detector-container -- -ra - py312-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 3.12 Ubuntu + py312-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -320,10 +320,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-resource-detector-azure -- -ra + run: tox -e py312-test-resource-detector-container -- -ra - pypy3-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure pypy-3.8 Ubuntu + pypy3-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -338,10 +338,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-resource-detector-azure -- -ra + run: tox -e pypy3-test-resource-detector-container -- -ra - py38-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 3.8 Ubuntu + py38-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -356,190 +356,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-sdk-extension-aws -- -ra + run: tox -e py38-test-resource-detector-azure-0 -- -ra - py39-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 3.9 Ubuntu + py38-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-sdk-extension-aws -- -ra + run: tox -e py38-test-resource-detector-azure-1 -- -ra - py310-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 3.10 Ubuntu + py39-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-sdk-extension-aws -- -ra + run: tox -e py39-test-resource-detector-azure-0 -- -ra - py311-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 3.11 Ubuntu + py39-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-sdk-extension-aws -- -ra + run: tox -e py39-test-resource-detector-azure-1 -- -ra - py312-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 3.12 Ubuntu + py310-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-sdk-extension-aws -- -ra + run: tox -e py310-test-resource-detector-azure-0 -- -ra - pypy3-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws pypy-3.8 Ubuntu + py310-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-sdk-extension-aws -- -ra + run: tox -e py310-test-resource-detector-azure-1 -- -ra - py38-test-distro_ubuntu-latest: - name: distro 3.8 Ubuntu + py311-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-distro -- -ra + run: tox -e py311-test-resource-detector-azure-0 -- -ra - py39-test-distro_ubuntu-latest: - name: distro 3.9 Ubuntu + py311-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-distro -- -ra + run: tox -e py311-test-resource-detector-azure-1 -- -ra - py310-test-distro_ubuntu-latest: - name: distro 3.10 Ubuntu + py312-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-distro -- -ra + run: tox -e py312-test-resource-detector-azure-0 -- -ra - py311-test-distro_ubuntu-latest: - name: distro 3.11 Ubuntu + py312-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-distro -- -ra + run: tox -e py312-test-resource-detector-azure-1 -- -ra - py312-test-distro_ubuntu-latest: - name: distro 3.12 Ubuntu + pypy3-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-distro -- -ra + run: tox -e pypy3-test-resource-detector-azure-0 -- -ra - pypy3-test-distro_ubuntu-latest: - name: distro pypy-3.8 Ubuntu + pypy3-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -554,10 +554,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-distro -- -ra + run: tox -e pypy3-test-resource-detector-azure-1 -- -ra - py38-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.8 Ubuntu + py38-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -572,190 +572,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-opentelemetry-instrumentation -- -ra + run: tox -e py38-test-sdk-extension-aws-0 -- -ra - py39-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.9 Ubuntu + py38-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation -- -ra + run: tox -e py38-test-sdk-extension-aws-1 -- -ra - py310-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.10 Ubuntu + py39-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-opentelemetry-instrumentation -- -ra + run: tox -e py39-test-sdk-extension-aws-0 -- -ra - py311-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.11 Ubuntu + py39-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-opentelemetry-instrumentation -- -ra + run: tox -e py39-test-sdk-extension-aws-1 -- -ra - py312-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.12 Ubuntu + py310-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-opentelemetry-instrumentation -- -ra + run: tox -e py310-test-sdk-extension-aws-0 -- -ra - pypy3-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation pypy-3.8 Ubuntu + py310-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-opentelemetry-instrumentation -- -ra + run: tox -e py310-test-sdk-extension-aws-1 -- -ra - py38-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.8 Ubuntu + py311-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aiohttp-client -- -ra + run: tox -e py311-test-sdk-extension-aws-0 -- -ra - py39-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.9 Ubuntu + py311-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-client -- -ra + run: tox -e py311-test-sdk-extension-aws-1 -- -ra - py310-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.10 Ubuntu + py312-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aiohttp-client -- -ra + run: tox -e py312-test-sdk-extension-aws-0 -- -ra - py311-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.11 Ubuntu + py312-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aiohttp-client -- -ra + run: tox -e py312-test-sdk-extension-aws-1 -- -ra - py312-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.12 Ubuntu + pypy3-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aiohttp-client -- -ra + run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra - pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client pypy-3.8 Ubuntu + pypy3-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -770,10 +770,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra + run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra - py38-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.8 Ubuntu + py38-test-distro_ubuntu-latest: + name: distro 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -788,10 +788,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aiohttp-server -- -ra + run: tox -e py38-test-distro -- -ra - py39-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.9 Ubuntu + py39-test-distro_ubuntu-latest: + name: distro 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -806,10 +806,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-server -- -ra + run: tox -e py39-test-distro -- -ra - py310-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.10 Ubuntu + py310-test-distro_ubuntu-latest: + name: distro 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -824,10 +824,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aiohttp-server -- -ra + run: tox -e py310-test-distro -- -ra - py311-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.11 Ubuntu + py311-test-distro_ubuntu-latest: + name: distro 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -842,10 +842,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aiohttp-server -- -ra + run: tox -e py311-test-distro -- -ra - py312-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.12 Ubuntu + py312-test-distro_ubuntu-latest: + name: distro 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -860,10 +860,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aiohttp-server -- -ra + run: tox -e py312-test-distro -- -ra - pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server pypy-3.8 Ubuntu + pypy3-test-distro_ubuntu-latest: + name: distro pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -878,10 +878,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra + run: tox -e pypy3-test-distro -- -ra - py38-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.8 Ubuntu + py38-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -896,10 +896,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aiopg -- -ra + run: tox -e py38-test-opentelemetry-instrumentation -- -ra - py39-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.9 Ubuntu + py39-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -914,10 +914,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aiopg -- -ra + run: tox -e py39-test-opentelemetry-instrumentation -- -ra - py310-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.10 Ubuntu + py310-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -932,10 +932,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aiopg -- -ra + run: tox -e py310-test-opentelemetry-instrumentation -- -ra - py311-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.11 Ubuntu + py311-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -950,10 +950,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aiopg -- -ra + run: tox -e py311-test-opentelemetry-instrumentation -- -ra - py312-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.12 Ubuntu + py312-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -968,10 +968,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aiopg -- -ra + run: tox -e py312-test-opentelemetry-instrumentation -- -ra - py38-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.8 Ubuntu + pypy3-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-opentelemetry-instrumentation -- -ra + + py38-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -986,10 +1004,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aws-lambda -- -ra + run: tox -e py38-test-instrumentation-aiohttp-client -- -ra - py39-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.9 Ubuntu + py39-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1004,10 +1022,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra + run: tox -e py39-test-instrumentation-aiohttp-client -- -ra - py310-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.10 Ubuntu + py310-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1022,10 +1040,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aws-lambda -- -ra + run: tox -e py310-test-instrumentation-aiohttp-client -- -ra - py311-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.11 Ubuntu + py311-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1040,10 +1058,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aws-lambda -- -ra + run: tox -e py311-test-instrumentation-aiohttp-client -- -ra - py312-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.12 Ubuntu + py312-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1058,10 +1076,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aws-lambda -- -ra + run: tox -e py312-test-instrumentation-aiohttp-client -- -ra - pypy3-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda pypy-3.8 Ubuntu + pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1076,10 +1094,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra + run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra - py38-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.8 Ubuntu + py38-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1094,10 +1112,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-botocore -- -ra + run: tox -e py38-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.9 Ubuntu + py39-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1112,10 +1130,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-botocore -- -ra + run: tox -e py39-test-instrumentation-aiohttp-server -- -ra - py310-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.10 Ubuntu + py310-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1130,10 +1148,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-botocore -- -ra + run: tox -e py310-test-instrumentation-aiohttp-server -- -ra - py311-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.11 Ubuntu + py311-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1148,10 +1166,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-botocore -- -ra + run: tox -e py311-test-instrumentation-aiohttp-server -- -ra - py312-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.12 Ubuntu + py312-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1166,10 +1184,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-botocore -- -ra + run: tox -e py312-test-instrumentation-aiohttp-server -- -ra - py38-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.8 Ubuntu + pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra + + py38-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1184,10 +1220,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-boto3sqs -- -ra + run: tox -e py38-test-instrumentation-aiopg -- -ra - py39-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.9 Ubuntu + py39-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1202,10 +1238,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra + run: tox -e py39-test-instrumentation-aiopg -- -ra - py310-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.10 Ubuntu + py310-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1220,10 +1256,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-boto3sqs -- -ra + run: tox -e py310-test-instrumentation-aiopg -- -ra - py311-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.11 Ubuntu + py311-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1238,10 +1274,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-boto3sqs -- -ra + run: tox -e py311-test-instrumentation-aiopg -- -ra - py312-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.12 Ubuntu + py312-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1256,154 +1292,154 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-boto3sqs -- -ra + run: tox -e py312-test-instrumentation-aiopg -- -ra - pypy3-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs pypy-3.8 Ubuntu + py38-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra + run: tox -e py38-test-instrumentation-aws-lambda -- -ra - py38-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.8 Ubuntu + py39-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-django-0 -- -ra + run: tox -e py39-test-instrumentation-aws-lambda -- -ra - py38-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.8 Ubuntu + py310-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-aws-lambda -- -ra - py38-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.8 Ubuntu + py311-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-django-2 -- -ra + run: tox -e py311-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.9 Ubuntu + py312-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra + run: tox -e py312-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.9 Ubuntu + pypy3-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra + run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.9 Ubuntu + py38-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra + run: tox -e py38-test-instrumentation-botocore -- -ra - py310-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.10 Ubuntu + py39-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-django-1 -- -ra + run: tox -e py39-test-instrumentation-botocore -- -ra - py310-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.10 Ubuntu + py310-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1418,10 +1454,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-django-3 -- -ra + run: tox -e py310-test-instrumentation-botocore -- -ra - py311-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.11 Ubuntu + py311-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1436,226 +1472,226 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-django-1 -- -ra + run: tox -e py311-test-instrumentation-botocore -- -ra - py311-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.11 Ubuntu + py312-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-django-3 -- -ra + run: tox -e py312-test-instrumentation-botocore -- -ra - py312-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.12 Ubuntu + py38-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-django-1 -- -ra + run: tox -e py38-test-instrumentation-boto3sqs -- -ra - py312-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.12 Ubuntu + py39-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-django-3 -- -ra + run: tox -e py39-test-instrumentation-boto3sqs -- -ra - pypy3-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 pypy-3.8 Ubuntu + py310-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-django-0 -- -ra + run: tox -e py310-test-instrumentation-boto3sqs -- -ra - pypy3-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 pypy-3.8 Ubuntu + py311-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-django-1 -- -ra + run: tox -e py311-test-instrumentation-boto3sqs -- -ra - py38-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.8 Ubuntu + py312-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-dbapi -- -ra + run: tox -e py312-test-instrumentation-boto3sqs -- -ra - py39-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.9 Ubuntu + pypy3-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-dbapi -- -ra + run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra - py310-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.10 Ubuntu + py38-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-dbapi -- -ra + run: tox -e py38-test-instrumentation-django-0 -- -ra - py311-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.11 Ubuntu + py38-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-dbapi -- -ra + run: tox -e py38-test-instrumentation-django-1 -- -ra - py312-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.12 Ubuntu + py38-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-dbapi -- -ra + run: tox -e py38-test-instrumentation-django-2 -- -ra - pypy3-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi pypy-3.8 Ubuntu + py39-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-dbapi -- -ra + run: tox -e py39-test-instrumentation-django-0 -- -ra - py38-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.8 Ubuntu + py39-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-boto -- -ra + run: tox -e py39-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.9 Ubuntu + py39-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1670,10 +1706,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-boto -- -ra + run: tox -e py39-test-instrumentation-django-2 -- -ra - py310-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.10 Ubuntu + py310-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1688,172 +1724,172 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-boto -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py311-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.11 Ubuntu + py310-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-boto -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py38-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.8 Ubuntu + py311-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py311-test-instrumentation-django-1 -- -ra - py38-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.8 Ubuntu + py311-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py311-test-instrumentation-django-3 -- -ra - py38-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.8 Ubuntu + py312-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py312-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.9 Ubuntu + py312-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py312-test-instrumentation-django-3 -- -ra - py39-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.9 Ubuntu + pypy3-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e pypy3-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.9 Ubuntu + pypy3-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e pypy3-test-instrumentation-django-1 -- -ra - py310-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.10 Ubuntu + py38-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py38-test-instrumentation-dbapi -- -ra - py310-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.10 Ubuntu + py39-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py39-test-instrumentation-dbapi -- -ra - py310-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.10 Ubuntu + py310-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1868,46 +1904,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - - py311-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra - - py311-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py310-test-instrumentation-dbapi -- -ra - py311-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.11 Ubuntu + py311-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1922,10 +1922,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py311-test-instrumentation-dbapi -- -ra - py312-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.12 Ubuntu + py312-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1940,100 +1940,100 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py312-test-instrumentation-dbapi -- -ra - py312-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.12 Ubuntu + pypy3-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e pypy3-test-instrumentation-dbapi -- -ra - py312-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.12 Ubuntu + py38-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py38-test-instrumentation-boto -- -ra - pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.8 Ubuntu + py39-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py39-test-instrumentation-boto -- -ra - pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.8 Ubuntu + py310-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py310-test-instrumentation-boto -- -ra - pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.8 Ubuntu + py311-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py311-test-instrumentation-boto -- -ra - py38-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.8 Ubuntu + py38-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2048,10 +2048,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-falcon-0 -- -ra + run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra - py38-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.8 Ubuntu + py38-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2066,10 +2066,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-falcon-1 -- -ra + run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra - py38-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.8 Ubuntu + py38-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2084,10 +2084,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-falcon-2 -- -ra + run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu + py39-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2102,10 +2102,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu + py39-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2120,10 +2120,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra - py39-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.9 Ubuntu + py39-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2138,10 +2138,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - py310-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.10 Ubuntu + py310-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2156,10 +2156,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-falcon-1 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - py310-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.10 Ubuntu + py310-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2174,28 +2174,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-falcon-2 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra - py311-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.11 Ubuntu + py310-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-falcon-1 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - py311-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.11 Ubuntu + py311-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2210,208 +2210,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-falcon-2 -- -ra - - py312-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-falcon-1 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra - py312-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.12 Ubuntu + py311-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-falcon-2 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra - pypy3-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 pypy-3.8 Ubuntu + py311-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra - pypy3-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 pypy-3.8 Ubuntu + py312-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra - pypy3-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 pypy-3.8 Ubuntu + py312-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra - py38-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.8 Ubuntu + py312-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-fastapi -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.9 Ubuntu + pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra - py310-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.10 Ubuntu + pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-fastapi -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra - py311-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.11 Ubuntu + pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-fastapi -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - py312-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.12 Ubuntu + py38-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-fastapi -- -ra + run: tox -e py38-test-instrumentation-falcon-0 -- -ra - pypy3-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi pypy-3.8 Ubuntu + py38-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-fastapi -- -ra + run: tox -e py38-test-instrumentation-falcon-1 -- -ra - py38-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.8 Ubuntu + py38-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2426,28 +2408,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-flask-0 -- -ra + run: tox -e py38-test-instrumentation-falcon-2 -- -ra - py38-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.8 Ubuntu + py39-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-flask-1 -- -ra + run: tox -e py39-test-instrumentation-falcon-0 -- -ra - py39-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.9 Ubuntu + py39-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2462,10 +2444,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra + run: tox -e py39-test-instrumentation-falcon-1 -- -ra - py39-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.9 Ubuntu + py39-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2480,10 +2462,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra + run: tox -e py39-test-instrumentation-falcon-2 -- -ra - py310-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.10 Ubuntu + py310-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2498,10 +2480,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-flask-0 -- -ra + run: tox -e py310-test-instrumentation-falcon-1 -- -ra - py310-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.10 Ubuntu + py310-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2516,10 +2498,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-flask-1 -- -ra + run: tox -e py310-test-instrumentation-falcon-2 -- -ra - py311-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.11 Ubuntu + py311-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2534,10 +2516,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-flask-0 -- -ra + run: tox -e py311-test-instrumentation-falcon-1 -- -ra - py311-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.11 Ubuntu + py311-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2552,10 +2534,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-flask-1 -- -ra + run: tox -e py311-test-instrumentation-falcon-2 -- -ra - py312-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.12 Ubuntu + py312-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2570,10 +2552,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-flask-0 -- -ra + run: tox -e py312-test-instrumentation-falcon-1 -- -ra - py312-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.12 Ubuntu + py312-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2588,406 +2570,424 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-flask-1 -- -ra + run: tox -e py312-test-instrumentation-falcon-2 -- -ra - py38-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.8 Ubuntu + pypy3-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-flask-2 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 Ubuntu + pypy3-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra - py310-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.10 Ubuntu + pypy3-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-flask-2 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra - py311-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.11 Ubuntu + py38-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-flask-2 -- -ra + run: tox -e py38-test-instrumentation-fastapi -- -ra - py312-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.12 Ubuntu + py39-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-flask-2 -- -ra + run: tox -e py39-test-instrumentation-fastapi -- -ra - pypy3-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 pypy-3.8 Ubuntu + py310-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-0 -- -ra + run: tox -e py310-test-instrumentation-fastapi -- -ra - pypy3-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 pypy-3.8 Ubuntu + py311-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-1 -- -ra + run: tox -e py311-test-instrumentation-fastapi -- -ra - py38-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.8 Ubuntu + py312-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-urllib -- -ra + run: tox -e py312-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.9 Ubuntu + pypy3-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra + run: tox -e pypy3-test-instrumentation-fastapi -- -ra - py310-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.10 Ubuntu + py38-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-urllib -- -ra + run: tox -e py38-test-instrumentation-flask-0 -- -ra - py311-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.11 Ubuntu + py38-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-1 -- -ra + + py39-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-urllib -- -ra + run: tox -e py39-test-instrumentation-flask-0 -- -ra - py312-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.12 Ubuntu + py39-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-urllib -- -ra + run: tox -e py39-test-instrumentation-flask-1 -- -ra - pypy3-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib pypy-3.8 Ubuntu + py310-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib -- -ra + run: tox -e py310-test-instrumentation-flask-0 -- -ra - py38-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.8 Ubuntu + py310-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-flask-1 -- -ra - py38-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.8 Ubuntu + py311-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-urllib3-1 -- -ra + run: tox -e py311-test-instrumentation-flask-0 -- -ra - py39-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.9 Ubuntu + py311-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.9 Ubuntu + py312-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py312-test-instrumentation-flask-0 -- -ra - py310-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.10 Ubuntu + py312-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-0 -- -ra + run: tox -e py312-test-instrumentation-flask-1 -- -ra - py310-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.10 Ubuntu + py38-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-1 -- -ra + run: tox -e py38-test-instrumentation-flask-2 -- -ra - py311-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.11 Ubuntu + py39-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + run: tox -e py39-test-instrumentation-flask-2 -- -ra - py311-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.11 Ubuntu + py310-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-flask-2 -- -ra - py312-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.12 Ubuntu + py311-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-flask-2 -- -ra - py312-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.12 Ubuntu + py312-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3002,10 +3002,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-1 -- -ra + run: tox -e py312-test-instrumentation-flask-2 -- -ra - pypy3-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 pypy-3.8 Ubuntu + pypy3-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3020,10 +3020,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra + run: tox -e pypy3-test-instrumentation-flask-0 -- -ra - pypy3-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 pypy-3.8 Ubuntu + pypy3-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3038,10 +3038,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra + run: tox -e pypy3-test-instrumentation-flask-1 -- -ra - py38-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.8 Ubuntu + py38-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3056,10 +3056,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-requests -- -ra + run: tox -e py38-test-instrumentation-urllib -- -ra - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 Ubuntu + py39-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3074,10 +3074,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra + run: tox -e py39-test-instrumentation-urllib -- -ra - py310-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.10 Ubuntu + py310-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3092,10 +3092,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-requests -- -ra + run: tox -e py310-test-instrumentation-urllib -- -ra - py311-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.11 Ubuntu + py311-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3110,10 +3110,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-requests -- -ra + run: tox -e py311-test-instrumentation-urllib -- -ra - py312-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.12 Ubuntu + py312-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3128,10 +3128,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-requests -- -ra + run: tox -e py312-test-instrumentation-urllib -- -ra - py38-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.8 Ubuntu + pypy3-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib -- -ra + + py38-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3146,190 +3164,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-starlette -- -ra + run: tox -e py38-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.9 Ubuntu + py38-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-starlette -- -ra + run: tox -e py38-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.10 Ubuntu + py39-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-starlette -- -ra + run: tox -e py39-test-instrumentation-urllib3-0 -- -ra - py311-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.11 Ubuntu + py39-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-starlette -- -ra + run: tox -e py39-test-instrumentation-urllib3-1 -- -ra - py312-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.12 Ubuntu + py310-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-starlette -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - pypy3-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette pypy-3.8 Ubuntu + py310-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py38-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.8 Ubuntu + py311-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-jinja2 -- -ra + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.9 Ubuntu + py311-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra + run: tox -e py311-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.10 Ubuntu + py312-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-jinja2 -- -ra + run: tox -e py312-test-instrumentation-urllib3-0 -- -ra - py311-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.11 Ubuntu + py312-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-jinja2 -- -ra + run: tox -e py312-test-instrumentation-urllib3-1 -- -ra - py312-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.12 Ubuntu + pypy3-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-jinja2 -- -ra + run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra - pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 pypy-3.8 Ubuntu + pypy3-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3344,10 +3362,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-jinja2 -- -ra + run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra - py38-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.8 Ubuntu + py38-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3362,10 +3380,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-logging -- -ra + run: tox -e py38-test-instrumentation-requests -- -ra - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.9 Ubuntu + py39-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3380,10 +3398,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra + run: tox -e py39-test-instrumentation-requests -- -ra - py310-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.10 Ubuntu + py310-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3398,10 +3416,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-logging -- -ra + run: tox -e py310-test-instrumentation-requests -- -ra - py311-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.11 Ubuntu + py311-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3416,10 +3434,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-logging -- -ra + run: tox -e py311-test-instrumentation-requests -- -ra - py312-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.12 Ubuntu + py312-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3434,28 +3452,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-logging -- -ra - - pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-logging -- -ra + run: tox -e py312-test-instrumentation-requests -- -ra - py38-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.8 Ubuntu + py38-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3470,10 +3470,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-exporter-richconsole -- -ra + run: tox -e py38-test-instrumentation-starlette -- -ra - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.9 Ubuntu + py39-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3488,10 +3488,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra + run: tox -e py39-test-instrumentation-starlette -- -ra - py310-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.10 Ubuntu + py310-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3506,10 +3506,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-exporter-richconsole -- -ra + run: tox -e py310-test-instrumentation-starlette -- -ra - py311-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.11 Ubuntu + py311-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3524,10 +3524,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-exporter-richconsole -- -ra + run: tox -e py311-test-instrumentation-starlette -- -ra - py312-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.12 Ubuntu + py312-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3542,10 +3542,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-exporter-richconsole -- -ra + run: tox -e py312-test-instrumentation-starlette -- -ra - pypy3-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole pypy-3.8 Ubuntu + pypy3-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3560,10 +3560,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-exporter-richconsole -- -ra + run: tox -e pypy3-test-instrumentation-starlette -- -ra - py38-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.8 Ubuntu + py38-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3578,10 +3578,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-exporter-prometheus-remote-write -- -ra + run: tox -e py38-test-instrumentation-jinja2 -- -ra - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.9 Ubuntu + py39-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3596,10 +3596,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra + run: tox -e py39-test-instrumentation-jinja2 -- -ra - py310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.10 Ubuntu + py310-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3614,10 +3614,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-exporter-prometheus-remote-write -- -ra + run: tox -e py310-test-instrumentation-jinja2 -- -ra - py311-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.11 Ubuntu + py311-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3632,10 +3632,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-exporter-prometheus-remote-write -- -ra + run: tox -e py311-test-instrumentation-jinja2 -- -ra - py312-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.12 Ubuntu + py312-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3650,10 +3650,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-exporter-prometheus-remote-write -- -ra + run: tox -e py312-test-instrumentation-jinja2 -- -ra - pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write pypy-3.8 Ubuntu + pypy3-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3668,10 +3668,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra + run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - py38-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.8 Ubuntu + py38-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3686,190 +3686,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-mysql-0 -- -ra + run: tox -e py38-test-instrumentation-logging -- -ra - py38-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.8 Ubuntu + py39-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-mysql-1 -- -ra + run: tox -e py39-test-instrumentation-logging -- -ra - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 Ubuntu + py310-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra + run: tox -e py310-test-instrumentation-logging -- -ra - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu + py311-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e py311-test-instrumentation-logging -- -ra - py310-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.10 Ubuntu + py312-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysql-0 -- -ra + run: tox -e py312-test-instrumentation-logging -- -ra - py310-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.10 Ubuntu + pypy3-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-instrumentation-logging -- -ra - py311-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.11 Ubuntu + py38-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysql-0 -- -ra + run: tox -e py38-test-exporter-richconsole -- -ra - py311-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.11 Ubuntu + py39-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysql-1 -- -ra + run: tox -e py39-test-exporter-richconsole -- -ra - py312-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.12 Ubuntu + py310-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysql-0 -- -ra + run: tox -e py310-test-exporter-richconsole -- -ra - py312-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.12 Ubuntu + py311-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysql-1 -- -ra + run: tox -e py311-test-exporter-richconsole -- -ra - pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.8 Ubuntu + py312-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra + run: tox -e py312-test-exporter-richconsole -- -ra - pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.8 Ubuntu + pypy3-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3884,10 +3884,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-exporter-richconsole -- -ra - py38-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.8 Ubuntu + py38-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3902,10 +3902,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-mysqlclient -- -ra + run: tox -e py38-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu + py39-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3920,10 +3920,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra + run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - py310-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.10 Ubuntu + py310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3938,10 +3938,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysqlclient -- -ra + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - py311-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.11 Ubuntu + py311-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3956,10 +3956,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysqlclient -- -ra + run: tox -e py311-test-exporter-prometheus-remote-write -- -ra - py312-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.12 Ubuntu + py312-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3974,10 +3974,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysqlclient -- -ra + run: tox -e py312-test-exporter-prometheus-remote-write -- -ra - pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.8 Ubuntu + pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3992,10 +3992,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra + run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra - py38-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.8 Ubuntu + py38-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4010,154 +4010,154 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-psycopg2 -- -ra + run: tox -e py38-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu + py38-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra + run: tox -e py38-test-instrumentation-mysql-1 -- -ra - py310-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.10 Ubuntu + py39-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2 -- -ra + run: tox -e py39-test-instrumentation-mysql-0 -- -ra - py311-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.11 Ubuntu + py39-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2 -- -ra + run: tox -e py39-test-instrumentation-mysql-1 -- -ra - py312-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.12 Ubuntu + py310-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2 -- -ra + run: tox -e py310-test-instrumentation-mysql-0 -- -ra - py38-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.8 Ubuntu + py310-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-psycopg -- -ra + run: tox -e py310-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu + py311-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra + run: tox -e py311-test-instrumentation-mysql-0 -- -ra - py310-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.10 Ubuntu + py311-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-psycopg -- -ra + run: tox -e py311-test-instrumentation-mysql-1 -- -ra - py311-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.11 Ubuntu + py312-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-psycopg -- -ra + run: tox -e py312-test-instrumentation-mysql-0 -- -ra - py312-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.12 Ubuntu + py312-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4172,10 +4172,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-psycopg -- -ra + run: tox -e py312-test-instrumentation-mysql-1 -- -ra - pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.8 Ubuntu + pypy3-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4190,28 +4190,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-psycopg -- -ra + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra - py38-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.8 Ubuntu + pypy3-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra + run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - py38-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.8 Ubuntu + py38-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4226,118 +4226,118 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py38-test-instrumentation-mysqlclient -- -ra - py38-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.8 Ubuntu + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py39-test-instrumentation-mysqlclient -- -ra - py38-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.8 Ubuntu + py310-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py310-test-instrumentation-mysqlclient -- -ra - py38-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.8 Ubuntu + py311-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py311-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 Ubuntu + py312-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py312-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 Ubuntu + pypy3-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 Ubuntu + py38-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py38-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu + py39-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4352,100 +4352,100 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py39-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 Ubuntu + py310-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py310-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 Ubuntu + py311-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py311-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 Ubuntu + py312-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py312-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 Ubuntu + py38-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py38-test-instrumentation-psycopg -- -ra - py310-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.10 Ubuntu + py39-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py39-test-instrumentation-psycopg -- -ra - py310-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.10 Ubuntu + py310-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4460,10 +4460,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py310-test-instrumentation-psycopg -- -ra - py311-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.11 Ubuntu + py311-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4478,40 +4478,40 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py311-test-instrumentation-psycopg -- -ra - py311-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.11 Ubuntu + py312-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py312-test-instrumentation-psycopg -- -ra - py311-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.11 Ubuntu + pypy3-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra + run: tox -e pypy3-test-instrumentation-psycopg -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 30e02c5634..0b6aa766f2 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,330 @@ env: jobs: + py38-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra + + py38-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra + + py38-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra + + py38-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra + + py38-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra + + py39-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + + py39-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + + py39-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + + py39-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + + py39-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra + + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra + + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra + + py310-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra + + py310-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra + + py311-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra + + py311-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra + + py311-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra + py311-test-instrumentation-pymemcache-3_ubuntu-latest: name: instrumentation-pymemcache-3 3.11 Ubuntu runs-on: ubuntu-latest @@ -2338,8 +2662,8 @@ jobs: - name: Run tests run: tox -e pypy3-test-util-http -- -ra - py38-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray 3.8 Ubuntu + py38-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2354,10 +2678,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-propagator-aws-xray -- -ra + run: tox -e py38-test-propagator-aws-xray-0 -- -ra - py39-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray 3.9 Ubuntu + py38-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-aws-xray-1 -- -ra + + py39-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2372,10 +2714,46 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-propagator-aws-xray -- -ra + run: tox -e py39-test-propagator-aws-xray-0 -- -ra + + py39-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-1 -- -ra + + py310-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-0 -- -ra - py310-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray 3.10 Ubuntu + py310-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2390,10 +2768,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-propagator-aws-xray -- -ra + run: tox -e py310-test-propagator-aws-xray-1 -- -ra - py311-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray 3.11 Ubuntu + py311-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2408,10 +2786,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-propagator-aws-xray -- -ra + run: tox -e py311-test-propagator-aws-xray-0 -- -ra - py312-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray 3.12 Ubuntu + py311-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-1 -- -ra + + py312-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2426,10 +2822,46 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-propagator-aws-xray -- -ra + run: tox -e py312-test-propagator-aws-xray-0 -- -ra + + py312-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-1 -- -ra + + pypy3-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra - pypy3-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray pypy-3.8 Ubuntu + pypy3-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2444,7 +2876,7 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray -- -ra + run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra py38-test-propagator-ot-trace_ubuntu-latest: name: propagator-ot-trace 3.8 Ubuntu diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index b342cdade7..eddd85e5f0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation ~= 0.48b0", - "opentelemetry-semantic-conventions ~= 0.48b0" + "opentelemetry-api ~= 1.28", + "opentelemetry-instrumentation ~= 0.49b0", + "opentelemetry-semantic-conventions ~= 0.49b0" ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt new file mode 100644 index 0000000000..7a15734872 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt @@ -0,0 +1,13 @@ +openai==1.26.0 +pydantic==2.8.2 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +packaging==24.0 +pytest==7.4.4 +pytest-vcr==1.0.2 +wrapt==1.16.0 +opentelemetry-api==1.28 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.28 # when updating, also update in pyproject.toml +opentelemetry-semantic-conventions==0.49b0 # when updating, also update in pyproject.toml + +-e instrumentation-genai/opentelemetry-instrumentation-openai-v2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt similarity index 74% rename from instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt index 09a7c75c16..ded849c8ee 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt @@ -6,6 +6,7 @@ packaging==24.0 pytest==7.4.4 pytest-vcr==1.0.2 wrapt==1.16.0 +# test with the latest version of opentelemetry-api, sdk, and semantic conventions -e opentelemetry-instrumentation -e instrumentation-genai/opentelemetry-instrumentation-openai-v2 diff --git a/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md b/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md index bb0292f819..bdbcdef927 100644 --- a/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md +++ b/propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Update `opentelemetry-api` version to 1.16 + ([#2961](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2961)) + ## Version 1.0.2 (2024-08-05) See [common CHANGELOG](../../CHANGELOG.md) for the changes in this and prior versions. diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 546c0790a2..14f16409b3 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-api ~= 1.12", + "opentelemetry-api ~= 1.16", ] [project.entry-points.opentelemetry_propagator] diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt new file mode 100644 index 0000000000..9880271676 --- /dev/null +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt @@ -0,0 +1,21 @@ +asgiref==3.8.1 +certifi==2024.7.4 +charset-normalizer==3.3.2 +Deprecated==1.2.14 +idna==3.7 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +pytest-benchmark==4.0.0 +requests==2.32.3 +tomli==2.0.1 +typing_extensions==4.12.2 +urllib3==2.2.2 +wrapt==1.16.0 +zipp==3.19.2 +opentelemetry-api==1.16 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.16 # when updating, also update in pyproject.toml + +-e propagator/opentelemetry-propagator-aws-xray diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt similarity index 80% rename from propagator/opentelemetry-propagator-aws-xray/test-requirements.txt rename to propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt index 6cbca62382..679800462e 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt @@ -15,4 +15,6 @@ typing_extensions==4.12.2 urllib3==2.2.2 wrapt==1.16.0 zipp==3.19.2 +# test with the latest version of opentelemetry-api, sdk, and semantic conventions + -e propagator/opentelemetry-propagator-aws-xray diff --git a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md index 5e16c83d63..517294d40a 100644 --- a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md +++ b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure consistently use of suppress_instrumentation utils ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) +- Update `opentelemetry-instrumentation` version to 0.44b0 + ([#2961](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2961)) ## Version 0.1.5 (2024-05-16) diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index 14952b751c..9427a1bee4 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-sdk ~= 1.21", - "opentelemetry-instrumentation ~= 0.43b0", + "opentelemetry-instrumentation ~= 0.44b0", ] [project.entry-points.opentelemetry_resource_detector] diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt b/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt new file mode 100644 index 0000000000..e694db3b52 --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt @@ -0,0 +1,15 @@ +asgiref==3.8.1 +Deprecated==1.2.14 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +opentelemetry-api==1.21 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.21 # when updating, also update in pyproject.toml +opentelemetry-instrumentation==0.44b0 # when updating, also update in pyproject.toml + +-e resource/opentelemetry-resource-detector-azure diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements.txt b/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt similarity index 74% rename from resource/opentelemetry-resource-detector-azure/test-requirements.txt rename to resource/opentelemetry-resource-detector-azure/test-requirements-1.txt index 353546f670..a2344e2871 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt @@ -8,5 +8,7 @@ pytest==7.4.4 typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 +# test with the latest version of opentelemetry-api, sdk, and semantic conventions + -e opentelemetry-instrumentation -e resource/opentelemetry-resource-detector-azure diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt similarity index 77% rename from sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt rename to sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt index 91a69c8d15..0861269324 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt @@ -10,4 +10,6 @@ tomli==2.0.1 typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 +opentelemetry-sdk==1.12 # when updating, also update in pyproject.toml + -e sdk-extension/opentelemetry-sdk-extension-aws diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt new file mode 100644 index 0000000000..222c3f1b67 --- /dev/null +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt @@ -0,0 +1,15 @@ +asgiref==3.8.1 +Deprecated==1.2.14 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +pytest-benchmark==4.0.0 +tomli==2.0.1 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +# test with the latest version of opentelemetry-api, sdk, and semantic conventions + +-e sdk-extension/opentelemetry-sdk-extension-aws diff --git a/tox.ini b/tox.ini index 62eeb03be2..61a74427d0 100644 --- a/tox.ini +++ b/tox.ini @@ -7,8 +7,8 @@ envlist = ; for specifying supported Python versions per package. ; instrumentation-openai - py3{8,9,10,11,12}-test-instrumentation-openai-v2 - pypy3-test-instrumentation-openai-v2 + py3{8,9,10,11,12}-test-instrumentation-openai-v2-{0,1} + pypy3-test-instrumentation-openai-v2-{0,1} lint-instrumentation-openai-v2 ; opentelemetry-resource-detector-container @@ -17,13 +17,13 @@ envlist = lint-resource-detector-container ; opentelemetry-resource-detector-azure - py3{8,9,10,11,12}-test-resource-detector-azure - pypy3-test-resource-detector-azure + py3{8,9,10,11,12}-test-resource-detector-azure-{0,1} + pypy3-test-resource-detector-azure-{0,1} lint-resource-detector-azure ; opentelemetry-sdk-extension-aws - py3{8,9,10,11,12}-test-sdk-extension-aws - pypy3-test-sdk-extension-aws + py3{8,9,10,11,12}-test-sdk-extension-aws-{0,1} + pypy3-test-sdk-extension-aws-{0,1} lint-sdk-extension-aws benchmark-sdk-extension-aws @@ -317,8 +317,8 @@ envlist = lint-util-http ; opentelemetry-propagator-aws-xray - py3{8,9,10,11,12}-test-propagator-aws-xray - pypy3-test-propagator-aws-xray + py3{8,9,10,11,12}-test-propagator-aws-xray-{0,1} + pypy3-test-propagator-aws-xray-{0,1} lint-propagator-aws-xray benchmark-propagator-aws-xray @@ -410,11 +410,16 @@ commands_pre = opentelemetry-instrumentation: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils opentelemetry-instrumentation: pip install -r {toxinidir}/opentelemetry-instrumentation/test-requirements.txt - openai: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - openai: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - openai: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - openai: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - openai: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt + # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API + # and SDK supported to test we are honoring it + openai-0: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt + # and the latest version of OTel API and SDK + openai-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + openai-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + openai-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + openai-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + openai-1: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt + lint-instrumentation-openai-v2: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt distro: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api distro: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -468,11 +473,6 @@ commands_pre = kafka-pythonng: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk kafka-pythonng: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt - openai: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - openai: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - openai: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - openai: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements.txt - confluent-kafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api confluent-kafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions confluent-kafka: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -771,11 +771,16 @@ commands_pre = httpx-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt lint-instrumentation-httpx: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt - sdk-extension-aws: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - sdk-extension-aws: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - sdk-extension-aws: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - sdk-extension-aws: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt + # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API + # and SDK supported to test we are honoring it + sdk-extension-aws-0: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt + # and the latest version of OTel API and SDK + sdk-extension-aws-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + sdk-extension-aws-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + sdk-extension-aws-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + sdk-extension-aws-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + sdk-extension-aws-1: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt + lint-sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt benchmark-sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt resource-detector-container: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api @@ -784,11 +789,16 @@ commands_pre = resource-detector-container: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils resource-detector-container: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-container/test-requirements.txt - resource-detector-azure: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - resource-detector-azure: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - resource-detector-azure: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - resource-detector-azure: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - resource-detector-azure: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements.txt + # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API + # and SDK supported to test we are honoring it + resource-detector-azure-0: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt + # and the latest version of OTel API and SDK + resource-detector-azure-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + resource-detector-azure-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + resource-detector-azure-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + resource-detector-azure-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + resource-detector-azure-1: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt + lint-resource-detector-azure: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt propagator-ot-trace: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api propagator-ot-trace: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions @@ -796,11 +806,16 @@ commands_pre = propagator-ot-trace: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils propagator-ot-trace: pip install -r {toxinidir}/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt - propagator-aws-xray: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - propagator-aws-xray: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - propagator-aws-xray: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - propagator-aws-xray: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt + # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API + # and SDK supported to test we are honoring it + propagator-aws-xray-0: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt + # and the latest version of OTel API and SDK + propagator-aws-xray-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + propagator-aws-xray-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + propagator-aws-xray-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + propagator-aws-xray-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + propagator-aws-xray-1: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt + lint-propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt benchmark-propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt processor-baggage: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api From 4a5bf9bd7efa9a6bf08588fcdea1280a48851b5e Mon Sep 17 00:00:00 2001 From: Nir Gazit Date: Thu, 7 Nov 2024 19:59:17 +0100 Subject: [PATCH 221/335] add nirga to GenAI component owners (#2962) --- .github/component_owners.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 621e00b005..478b68f53f 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -71,3 +71,4 @@ components: - karthikscale3 - lmolkova - lzchen + - nirga From ca4d5170d0e4e37c21b826c6d61cd8343e930a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:18:51 -0300 Subject: [PATCH 222/335] fix: remove opentelemetry-instrumentation-test package from bootstrap_gen (#2969) --- CHANGELOG.md | 11 +- instrumentation/README.md | 1 - .../LICENSE | 201 ------------------ .../README.rst | 25 --- .../pyproject.toml | 49 ----- .../instrumentation/test/__init__.py | 17 -- .../instrumentation/test/package.py | 20 -- .../instrumentation/test/version.py | 15 -- .../test-requirements.txt | 13 -- .../tests/__init__.py | 0 .../pyproject.toml | 1 - .../instrumentation/bootstrap_gen.py | 1 - scripts/generate_instrumentation_bootstrap.py | 4 +- .../generate_instrumentation_metapackage.py | 4 + 14 files changed, 17 insertions(+), 345 deletions(-) delete mode 100644 instrumentation/opentelemetry-instrumentation-test/LICENSE delete mode 100644 instrumentation/opentelemetry-instrumentation-test/README.rst delete mode 100644 instrumentation/opentelemetry-instrumentation-test/pyproject.toml delete mode 100644 instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py delete mode 100644 instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py delete mode 100644 instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py delete mode 100644 instrumentation/opentelemetry-instrumentation-test/test-requirements.txt delete mode 100644 instrumentation/opentelemetry-instrumentation-test/tests/__init__.py diff --git a/CHANGELOG.md b/CHANGELOG.md index d0794f81a2..e1378d7ad9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +### Fixed + +### Breaking changes + +- Drop `opentelemetry-instrumentation-test` package from default instrumentation list + ([#2969](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2969)) + ## Version 1.28.0/0.49b0 (2024-11-05) ### Added @@ -30,7 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-aiokafka` Wrap `AIOKafkaConsumer.getone()` instead of `AIOKafkaConsumer.__anext__` ([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874)) -- `opentelemetry-instrumentation-confluent-kafka` Fix to allow `topic` to be extracted from `kwargs` in `produce()` +- `opentelemetry-instrumentation-confluent-kafka` Fix to allow `topic` to be extracted from `kwargs` in `produce()` ([#2901])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2901) - `opentelemetry-instrumentation-system-metrics` Update metric units to conform to UCUM conventions. ([#2922](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2922)) diff --git a/instrumentation/README.md b/instrumentation/README.md index 6bb47f6f9c..b87bf6f844 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -43,7 +43,6 @@ | [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | experimental | [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette ~= 0.13.0 | Yes | experimental | [opentelemetry-instrumentation-system-metrics](./opentelemetry-instrumentation-system-metrics) | psutil >= 5 | No | experimental -| [opentelemetry-instrumentation-test](./opentelemetry-instrumentation-test) | test | No | migration | [opentelemetry-instrumentation-threading](./opentelemetry-instrumentation-threading) | threading | No | experimental | [opentelemetry-instrumentation-tornado](./opentelemetry-instrumentation-tornado) | tornado >= 5.1.1 | Yes | experimental | [opentelemetry-instrumentation-tortoiseorm](./opentelemetry-instrumentation-tortoiseorm) | tortoise-orm >= 0.17.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-test/LICENSE b/instrumentation/opentelemetry-instrumentation-test/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-test/README.rst b/instrumentation/opentelemetry-instrumentation-test/README.rst deleted file mode 100644 index fe5aeea554..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/README.rst +++ /dev/null @@ -1,25 +0,0 @@ -OpenTelemetry TEst Middleware -============================= - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-test.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-test/ - - -This library provides a test middleware that can be used on any test framework. - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation-test - -References ----------- - -* `OpenTelemetry TEst Middleware `_ -* `OpenTelemetry Project `_ -* `WSGI `_ -* `OpenTelemetry Python Examples `_ diff --git a/instrumentation/opentelemetry-instrumentation-test/pyproject.toml b/instrumentation/opentelemetry-instrumentation-test/pyproject.toml deleted file mode 100644 index 78e12624d0..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/pyproject.toml +++ /dev/null @@ -1,49 +0,0 @@ -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project] -name = "opentelemetry-instrumentation-test" -dynamic = ["version"] -description = "test Middleware for OpenTelemetry" -readme = "README.rst" -license = "Apache-2.0" -requires-python = ">=3.8" -authors = [ - { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, -] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", -] -dependencies = [ - "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation ~= 0.47b0", - "opentelemetry-semantic-conventions == 0.47b0", -] - -[project.optional-dependencies] -instruments = [] - -[project.urls] -Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-test" - -[tool.hatch.version] -path = "src/opentelemetry/instrumentation/test/version.py" - -[tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", -] - -[tool.hatch.build.targets.wheel] -packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py deleted file mode 100644 index 3401275a73..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -This library provides a WSGI middleware that can be used on any WSGI framework -(such as Django / Flask / Web.py) to track requests timing through OpenTelemetry. -""" diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py deleted file mode 100644 index 361eac89c9..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -_instruments = tuple() - -_supports_metrics = False - -_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py b/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py deleted file mode 100644 index 0d3adda0a2..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__version__ = "1.0.0b.dev" diff --git a/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt deleted file mode 100644 index e8f9e579c6..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -asgiref==3.8.1 -Deprecated==1.2.14 -iniconfig==2.0.0 -packaging==24.0 -pluggy==1.5.0 -py-cpuinfo==9.0.0 -pytest==7.4.4 -tomli==2.0.1 -typing_extensions==4.9.0 -wrapt==1.16.0 -zipp==3.19.2 -opentelemetry-instrumentation==0.48b0 --e instrumentation/opentelemetry-instrumentation-test diff --git a/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 29a3d51a96..11eae92ba6 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -71,7 +71,6 @@ dependencies = [ "opentelemetry-instrumentation-sqlite3==0.50b0.dev", "opentelemetry-instrumentation-starlette==0.50b0.dev", "opentelemetry-instrumentation-system-metrics==0.50b0.dev", - "opentelemetry-instrumentation-test==1.0.0b.dev", "opentelemetry-instrumentation-threading==0.50b0.dev", "opentelemetry-instrumentation-tornado==0.50b0.dev", "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 8192b1fff9..1100a5c51b 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -194,7 +194,6 @@ "opentelemetry-instrumentation-dbapi==0.50b0.dev", "opentelemetry-instrumentation-logging==0.50b0.dev", "opentelemetry-instrumentation-sqlite3==0.50b0.dev", - "opentelemetry-instrumentation-test==1.0.0b.dev", "opentelemetry-instrumentation-threading==0.50b0.dev", "opentelemetry-instrumentation-urllib==0.50b0.dev", "opentelemetry-instrumentation-wsgi==0.50b0.dev", diff --git a/scripts/generate_instrumentation_bootstrap.py b/scripts/generate_instrumentation_bootstrap.py index 57af33e303..65669e42ff 100755 --- a/scripts/generate_instrumentation_bootstrap.py +++ b/scripts/generate_instrumentation_bootstrap.py @@ -58,7 +58,9 @@ # in all environments. Instead, users who need AWS Lambda support can opt-in # by manually adding it to their environment. # See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2787 -packages_to_exclude = ["opentelemetry-instrumentation-aws-lambda"] +packages_to_exclude = [ + "opentelemetry-instrumentation-aws-lambda", +] def main(): diff --git a/scripts/generate_instrumentation_metapackage.py b/scripts/generate_instrumentation_metapackage.py index ad5d0b5e3a..fd4f9bfe7a 100755 --- a/scripts/generate_instrumentation_metapackage.py +++ b/scripts/generate_instrumentation_metapackage.py @@ -29,9 +29,13 @@ root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) base_instrumentation_path = os.path.join(root_path, "instrumentation") +packages_to_exclude = [] + def get_instrumentation_packages(): for instrumentation in sorted(os.listdir(base_instrumentation_path)): + if instrumentation in packages_to_exclude: + continue instrumentation_path = os.path.join( base_instrumentation_path, instrumentation ) From 1d8286c08a13ef9687271a1e484630a380357b7b Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:18:05 -0800 Subject: [PATCH 223/335] Update tests to work with SQLAlchemy 2 (#2976) --- .github/workflows/test_1.yml | 108 ++++++++++++++++++ CHANGELOG.md | 3 + .../test-requirements-2.txt | 13 +++ .../tests/test_sqlalchemy.py | 53 +++++---- .../tests/test_sqlcommenter.py | 17 +-- tox.ini | 6 +- 6 files changed, 167 insertions(+), 33 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 0b6aa766f2..227c891d0b 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -1492,6 +1492,24 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra + py38-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sqlalchemy-2 -- -ra + py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: name: instrumentation-sqlalchemy-1 3.9 Ubuntu runs-on: ubuntu-latest @@ -1510,6 +1528,24 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra + py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: name: instrumentation-sqlalchemy-1 3.10 Ubuntu runs-on: ubuntu-latest @@ -1528,6 +1564,24 @@ jobs: - name: Run tests run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra + py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra + py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: name: instrumentation-sqlalchemy-1 3.11 Ubuntu runs-on: ubuntu-latest @@ -1546,6 +1600,24 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra + py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra + py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: name: instrumentation-sqlalchemy-1 3.12 Ubuntu runs-on: ubuntu-latest @@ -1564,6 +1636,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra + py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra + pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: name: instrumentation-sqlalchemy-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1600,6 +1690,24 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra + pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra + py38-test-instrumentation-redis_ubuntu-latest: name: instrumentation-redis 3.8 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index e1378d7ad9..c9718639d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-sqlalchemy` Update unit tests to run with SQLALchemy 2 + ([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976)) + ### Fixed ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt new file mode 100644 index 0000000000..757224a25b --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt @@ -0,0 +1,13 @@ +aiosqlite==0.20.0 +asgiref==3.8.1 +Deprecated==1.2.14 +greenlet==3.1.1 +iniconfig==2.0.0 +packaging==24.1 +pluggy==1.5.0 +pytest==7.4.4 +SQLAlchemy==2.0.36 +typing_extensions==4.12.2 +wrapt==1.16.0 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-sqlalchemy diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py index f729fa6d80..957ae16237 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py @@ -17,7 +17,10 @@ import pytest import sqlalchemy -from sqlalchemy import create_engine +from sqlalchemy import ( + create_engine, + text, +) from opentelemetry import trace from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor @@ -43,12 +46,14 @@ def test_trace_integration(self): tracer_provider=self.tracer_provider, ) cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() - cnx.execute("/* leading comment */ SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + cnx.execute(text("/* leading comment */ SELECT 1 + 1;")).fetchall() cnx.execute( - "/* leading comment */ SELECT 1 + 1; /* trailing comment */" + text( + "/* leading comment */ SELECT 1 + 1; /* trailing comment */" + ) ).fetchall() - cnx.execute("SELECT 1 + 1; /* trailing comment */").fetchall() + cnx.execute(text("SELECT 1 + 1; /* trailing comment */")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 5) @@ -76,9 +81,9 @@ def test_instrument_two_engines(self): ) cnx_1 = engine_1.connect() - cnx_1.execute("SELECT 1 + 1;").fetchall() + cnx_1.execute(text("SELECT 1 + 1;")).fetchall() cnx_2 = engine_2.connect() - cnx_2.execute("SELECT 1 + 1;").fetchall() + cnx_2.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() # 2 queries + 2 engine connect @@ -111,7 +116,7 @@ async def run(): engine=engine.sync_engine, tracer_provider=self.tracer_provider ) async with engine.connect() as cnx: - await cnx.execute(sqlalchemy.text("SELECT 1 + 1;")) + await cnx.execute(text("SELECT 1 + 1;")) spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) # first span - the connection to the db @@ -144,7 +149,7 @@ def test_not_recording(self): tracer_provider=self.tracer_provider, ) cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() self.assertFalse(mock_span.is_recording()) self.assertTrue(mock_span.is_recording.called) self.assertFalse(mock_span.set_attribute.called) @@ -156,7 +161,7 @@ def test_create_engine_wrapper(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) @@ -187,7 +192,7 @@ def test_create_engine_wrapper_enable_commenter(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() # sqlcommenter self.assertRegex( self.caplog.records[-2].getMessage(), @@ -207,7 +212,7 @@ def test_create_engine_wrapper_enable_commenter_otel_values_false(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() # sqlcommenter self.assertRegex( self.caplog.records[-2].getMessage(), @@ -233,7 +238,7 @@ def test_custom_tracer_provider(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) @@ -258,7 +263,7 @@ async def run(): engine = create_async_engine("sqlite+aiosqlite:///:memory:") async with engine.connect() as cnx: - await cnx.execute(sqlalchemy.text("SELECT 1 + 1;")) + await cnx.execute(text("SELECT 1 + 1;")) spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) # first span - the connection to the db @@ -299,7 +304,7 @@ async def run(): engine = create_async_engine("sqlite+aiosqlite:///:memory:") async with engine.connect() as cnx: - await cnx.execute(sqlalchemy.text("SELECT 1;")) + await cnx.execute(text("SELECT 1;")) # sqlcommenter self.assertRegex( self.caplog.records[1].getMessage(), @@ -330,7 +335,7 @@ async def run(): engine = create_async_engine("sqlite+aiosqlite:///:memory:") async with engine.connect() as cnx: - await cnx.execute(sqlalchemy.text("SELECT 1;")) + await cnx.execute(text("SELECT 1;")) # sqlcommenter self.assertRegex( self.caplog.records[1].getMessage(), @@ -346,7 +351,7 @@ def test_uninstrument(self): tracer_provider=self.tracer_provider, ) cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) @@ -359,10 +364,10 @@ def test_uninstrument(self): self.memory_exporter.clear() SQLAlchemyInstrumentor().uninstrument() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() engine2 = create_engine("sqlite:///:memory:") cnx2 = engine2.connect() - cnx2.execute("SELECT 2 + 2;").fetchall() + cnx2.execute(text("SELECT 2 + 2;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) @@ -371,7 +376,7 @@ def test_uninstrument(self): tracer_provider=self.tracer_provider, ) cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) @@ -384,13 +389,13 @@ def test_uninstrument_without_engine(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) self.memory_exporter.clear() SQLAlchemyInstrumentor().uninstrument() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) @@ -401,7 +406,7 @@ def test_no_op_tracer_provider(self): tracer_provider=trace.NoOpTracerProvider(), ) cnx = engine.connect() - cnx.execute("SELECT 1 + 1;").fetchall() + cnx.execute(text("SELECT 1 + 1;")).fetchall() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) @@ -420,7 +425,7 @@ def make_shortlived_engine(): # collection weakref.finalize(engine, callback) with engine.connect() as conn: - conn.execute("SELECT 1 + 1;").fetchall() + conn.execute(text("SELECT 1 + 1;")).fetchall() for _ in range(0, 5): make_shortlived_engine() diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py index f13c552bf4..ec2fc51e5b 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py @@ -14,7 +14,10 @@ import logging import pytest -from sqlalchemy import create_engine +from sqlalchemy import ( + create_engine, + text, +) from opentelemetry import context from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor @@ -37,7 +40,7 @@ def test_sqlcommenter_disabled(self): engine=engine, tracer_provider=self.tracer_provider ) cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() self.assertEqual(self.caplog.records[-2].getMessage(), "SELECT 1;") @@ -50,7 +53,7 @@ def test_sqlcommenter_enabled(self): commenter_options={"db_framework": False}, ) cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() self.assertRegex( self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", @@ -68,7 +71,7 @@ def test_sqlcommenter_enabled_otel_values_false(self): }, ) cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() self.assertRegex( self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)'\*/;", @@ -90,7 +93,7 @@ def test_sqlcommenter_flask_integration(self): ) context.attach(sqlcommenter_context) - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() self.assertRegex( self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)',flask=1,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", @@ -105,7 +108,7 @@ def test_sqlcommenter_enabled_create_engine_after_instrumentation(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() self.assertRegex( self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", @@ -120,5 +123,5 @@ def test_sqlcommenter_disabled_create_engine_after_instrumentation(self): engine = create_engine("sqlite:///:memory:") cnx = engine.connect() - cnx.execute("SELECT 1;").fetchall() + cnx.execute(text("SELECT 1;")).fetchall() self.assertEqual(self.caplog.records[-2].getMessage(), "SELECT 1;") diff --git a/tox.ini b/tox.ini index 61a74427d0..cc5e509abc 100644 --- a/tox.ini +++ b/tox.ini @@ -263,8 +263,9 @@ envlist = ; below mean these dependencies are being used: ; 0: sqlalchemy>=1.1,<1.2 ; 1: sqlalchemy~=1.4 aiosqlite - py3{8,9,10,11,12}-test-instrumentation-sqlalchemy-{1} - pypy3-test-instrumentation-sqlalchemy-{0,1} + ; 2: sqlalchemy~=2.0.0 + py3{8,9,10,11,12}-test-instrumentation-sqlalchemy-{1,2} + pypy3-test-instrumentation-sqlalchemy-{0,1,2} lint-instrumentation-sqlalchemy ; opentelemetry-instrumentation-redis @@ -746,6 +747,7 @@ commands_pre = sqlalchemy: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils sqlalchemy-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt sqlalchemy-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt + sqlalchemy-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt lint-instrumentation-sqlalchemy: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt elasticsearch: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api From 1d6968b672eeefda824daefd1f0238346287976f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Thu, 7 Nov 2024 20:39:16 -0300 Subject: [PATCH 224/335] fix: teach instrument version constraint for sqlalchemy (#2971) --- CHANGELOG.md | 2 ++ instrumentation/README.md | 2 +- .../opentelemetry-instrumentation-sqlalchemy/pyproject.toml | 2 +- .../src/opentelemetry/instrumentation/sqlalchemy/package.py | 2 +- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9718639d7..6be2429f06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking changes +- `opentelemetry-instrumentation-sqlalchemy` teach instruments version + ([#2971](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2971)) - Drop `opentelemetry-instrumentation-test` package from default instrumentation list ([#2969](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2969)) diff --git a/instrumentation/README.md b/instrumentation/README.md index b87bf6f844..fb601266ea 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -39,7 +39,7 @@ | [opentelemetry-instrumentation-redis](./opentelemetry-instrumentation-redis) | redis >= 2.6 | No | experimental | [opentelemetry-instrumentation-remoulade](./opentelemetry-instrumentation-remoulade) | remoulade >= 0.50 | No | experimental | [opentelemetry-instrumentation-requests](./opentelemetry-instrumentation-requests) | requests ~= 2.0 | Yes | migration -| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy | Yes | experimental +| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy >= 1.0.0, < 2.1.0 | Yes | experimental | [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | experimental | [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette ~= 0.13.0 | Yes | experimental | [opentelemetry-instrumentation-system-metrics](./opentelemetry-instrumentation-system-metrics) | psutil >= 5 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index f8ce651b6c..d6d8c7aff9 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "sqlalchemy", + "sqlalchemy >= 1.0.0, < 2.1.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py index e3029f57b6..77b148e51c 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -_instruments = ("sqlalchemy",) +_instruments = ("sqlalchemy >= 1.0.0, < 2.1.0",) _supports_metrics = True diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 1100a5c51b..2e7b5532f3 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -161,7 +161,7 @@ "instrumentation": "opentelemetry-instrumentation-requests==0.50b0.dev", }, { - "library": "sqlalchemy", + "library": "sqlalchemy >= 1.0.0, < 2.1.0", "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.50b0.dev", }, { From 46b14662f8fe8f405fbff3544d65ab1f216b714d Mon Sep 17 00:00:00 2001 From: Guangya Liu Date: Thu, 7 Nov 2024 19:07:33 -0500 Subject: [PATCH 225/335] adding gyliu513 as genai reviewer (#2972) --- .github/component_owners.yml | 1 + CONTRIBUTING.md | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 478b68f53f..3aeb90b297 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -71,4 +71,5 @@ components: - karthikscale3 - lmolkova - lzchen + - gyliu513 - nirga diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 798b1ef571..a0cdbfa8ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ Please also read the [OpenTelemetry Contributor Guide](https://github.com/open-t * [Testing against a different Core repo branch/commit](#testing-against-a-different-core-repo-branchcommit) * [Style Guide](#style-guide) * [Guideline for instrumentations](#guideline-for-instrumentations) -* [Guidance for GenAI instrumentations](#guideline-for-genai-instrumentations) +* [Guideline for GenAI instrumentations](#guideline-for-genai-instrumentations) * [Expectations from contributors](#expectations-from-contributors) ## Find a Buddy and get Started Quickly @@ -273,13 +273,13 @@ Below is a checklist of things to be mindful of when implementing a new instrume - ex. - All instrumentations have the same version. If you are going to develop a new instrumentation it would probably have `X.Y.dev` version and depends on `opentelemetry-instrumentation` and `opentelemetry-semantic-conventions` for the same version. That means that if you want to install your instrumentation you need to install its dependencies from this repo and the core repo also from git. -## Guidance for GenAI instrumentations +## Guideline for GenAI instrumentations -Instrumentations that relate to [Generative AI](https://opentelemetry.io/docs/specs/semconv/gen-ai/) systems will be placed in the [genai](./instrumentation/genai) folder. This section covers contributions related to those instrumentations. Please note that the [guidelines for instrumentations](#guideline-for-instrumentations) and [expectations from contributors](#expectations-from-contributors) still apply. +Instrumentations that relate to [Generative AI](https://opentelemetry.io/docs/specs/semconv/gen-ai/) systems will be placed in the [instrumentation-genai](./instrumentation-genai) folder. This section covers contributions related to those instrumentations. Please note that the [guidelines for instrumentations](#guideline-for-instrumentations) and [expectations from contributors](#expectations-from-contributors) still apply. ### Get Involved -* Reviewing PRs: If you would like to be tagged as reviewer in new PRs related to these instrumentations, please submit a PR to add your GitHub handle to [component_owners.yml](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2944/.github/component_owners.yml) under the corresponding instrumentation folder(s). +* Reviewing PRs: If you would like to be tagged as reviewer in new PRs related to these instrumentations, please submit a PR to add your GitHub handle to [component_owners.yml](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/component_owners.yml) under the corresponding instrumentation folder(s). * Approving PRs: If you would like to be able to approve PRs related to these instrumentations, you must join [opentelemetry-python-contrib-approvers](https://github.com/orgs/open-telemetry/teams/opentelemetry-python-contrib-approvers) team. Please ask one of the [Python contrib maintainers](https://github.com/orgs/open-telemetry/teams/opentelemetry-python-contrib-maintainers) to be accepted into the team. From 4606cf2c106392f1a8b9b3725d19b645e3f3cb0e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:03:39 -0600 Subject: [PATCH 226/335] Copy changelog updates from package-release/opentelemetry-instrumentation-openai-v2/v2.0bx (#2982) --- .../opentelemetry-instrumentation-openai-v2/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index adac1168c4..2fdeeea74f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -## Version 2.0b0 (2024-11-05) +## Version 2.0b0 (2024-11-08) - Use generic `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` environment variable to control if content of prompt, completion, and other messages is captured. From bf8e2814ea9b0a608887dc1970de277c4bb4e28a Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Tue, 12 Nov 2024 00:12:26 +0800 Subject: [PATCH 227/335] opentelemetry-instrumentation-openai-v2: add codefromthecrypt and fix yaml fixture (#2989) --- .github/component_owners.yml | 1 + .../tests/cassettes/test_chat_completion_404.yaml | 12 +++++++----- .../tests/conftest.py | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 3aeb90b297..1e89d59567 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -73,3 +73,4 @@ components: - lzchen - gyliu513 - nirga + - codefromthecrypt diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml index ae00c6ef70..0782cba71d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml @@ -24,7 +24,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -34,7 +34,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -56,13 +58,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd0709dffd19c8c-SIN + - 8e0ca7056be15f93-SIN Connection: - keep-alive Content-Type: - application/json; charset=utf-8 Date: - - Mon, 04 Nov 2024 00:20:44 GMT + - Mon, 11 Nov 2024 07:43:38 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -80,7 +82,7 @@ interactions: vary: - Origin x-request-id: - - req_e08854c4f7d5104af6fdc755caed30fc + - req_75175efff56c313161c136c479e082ac status: code: 404 message: Not Found diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 84a9bf2692..899b2f122c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -161,7 +161,7 @@ def deserialize(cassette_string): return yaml.load(cassette_string, Loader=yaml.Loader) -@pytest.fixture(scope="module") +@pytest.fixture(scope="module", autouse=True) def fixture_vcr(vcr): vcr.register_serializer("yaml", PrettyPrintJSONBody) return vcr From 66a678072133ad242a03b968476ea6b29e749907 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Mon, 11 Nov 2024 10:53:42 -0800 Subject: [PATCH 228/335] Add generate-workflows usage to CONTRIBUTING (#2977) --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0cdbfa8ec..633a356c40 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,6 +68,7 @@ You can run `tox` with the following arguments: Python version * `tox -e spellcheck` to run a spellcheck on all the code * `tox -e lint-some-package` to run lint checks on `some-package` +* `tox -e generate-workflows` to run creation of new CI workflows if tox environments have been updated * `tox -e ruff` to run ruff linter and formatter checks against the entire codebase `ruff check` and `ruff format` are executed when `tox -e ruff` is run. We strongly recommend you to configure [pre-commit](https://pre-commit.com/) locally to run `ruff` automatically before each commit by installing it as git hooks. You just need to [install pre-commit](https://pre-commit.com/#install) in your environment: @@ -297,6 +298,7 @@ When updating the minimum supported Python version remember to: - Remove the version in `pyproject.toml` trove classifiers - Remove the version from `tox.ini` +- Update github workflows accordingly with `tox -e generate-workflows` - Search for `sys.version_info` usage and remove code for unsupported versions - Bump `py-version` in `.pylintrc` for Python version dependent checks @@ -306,6 +308,6 @@ When adding support for a new Python release remember to: - Add the version in `tox.ini` - Add the version in `pyproject.toml` trove classifiers -- Update github workflows accordingly; lint and benchmarks use the latest supported version +- Update github workflows accordingly with `tox -e generate-workflows`; lint and benchmarks use the latest supported version - Update `.pre-commit-config.yaml` - Update tox examples in the documentation From b6a6f75834a5752eb261c7d323aab1d769cdd9b4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 11 Nov 2024 11:02:20 -0800 Subject: [PATCH 229/335] publish to pypi (#2980) (#2987) --- .github/workflows/package-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index 01c598f7f1..86a2375f1f 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -102,9 +102,9 @@ jobs: - name: Publish to PyPI env: TWINE_USERNAME: '__token__' - TWINE_PASSWORD: ${{ secrets.test_pypi_token }} + TWINE_PASSWORD: ${{ secrets.pypi_password }} run: | - twine upload --repository testpypi --skip-existing --verbose dist/* + twine upload --skip-existing --verbose dist/* - name: Generate release notes env: From c28f7c978e9c06724f079314822c8f7777d1144d Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 12 Nov 2024 09:18:09 -0800 Subject: [PATCH 230/335] re-add testpypi publish step (#2991) --- .github/workflows/release.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 964d6f93df..7d7b18edc8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,14 +81,13 @@ jobs: # rejected by pypi (e.g "3 - Beta"). This would cause a failure during the # middle of the package upload causing the action to fail, and certain packages # might have already been updated, this would be bad. - # EDIT: 5/31/2024 - TestPypi now requires a verified email. Commenting out as a temporary measure - # until we found TestPypi credentials. - # - name: Publish to TestPyPI - # env: - # TWINE_USERNAME: '__token__' - # TWINE_PASSWORD: ${{ secrets.test_pypi_token }} - # run: | - # twine upload --repository testpypi --skip-existing --verbose dist/* + + - name: Publish to TestPyPI + env: + TWINE_USERNAME: '__token__' + TWINE_PASSWORD: ${{ secrets.test_pypi_token }} + run: | + twine upload --repository testpypi --skip-existing --verbose dist/* - name: Publish to PyPI env: From 89a0b28a092bd5a5d6760a2855198f9477573a5d Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Wed, 13 Nov 2024 05:01:49 +0800 Subject: [PATCH 231/335] opentelemetry-instrumentation-openai-v2: scrub cookie from tests (#2993) --- .../cassettes/test_chat_completion_404.yaml | 10 +- .../test_chat_completion_extra_params.yaml | 34 ++- ...test_chat_completion_multiple_choices.yaml | 42 +-- ...completion_multiple_choices_streaming.yaml | 252 +++++++++--------- ...n_multiple_tools_streaming_no_content.yaml | 56 ++-- ...multiple_tools_streaming_with_content.yaml | 56 ++-- .../test_chat_completion_streaming.yaml | 34 +-- ...hat_completion_streaming_not_complete.yaml | 34 +-- ...chat_completion_tool_calls_no_content.yaml | 87 +++--- ...at_completion_tool_calls_with_content.yaml | 85 +++--- .../test_chat_completion_with_content.yaml | 38 +-- .../tests/conftest.py | 11 +- 12 files changed, 403 insertions(+), 336 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml index 0782cba71d..fb713363d5 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml @@ -15,6 +15,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -58,13 +60,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8e0ca7056be15f93-SIN + - 8e1225a16c283d93-SIN Connection: - keep-alive Content-Type: - application/json; charset=utf-8 Date: - - Mon, 11 Nov 2024 07:43:38 GMT + - Mon, 11 Nov 2024 23:43:52 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -76,13 +78,13 @@ interactions: - h3=":443"; ma=86400 content-length: - '231' - openai-organization: test_organization + openai-organization: test_openai_org_id strict-transport-security: - max-age=31536000; includeSubDomains; preload vary: - Origin x-request-id: - - req_75175efff56c313161c136c479e082ac + - req_c3e0f92d7b5426d1a4a17bb3d39953ea status: code: 404 message: Not Found diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml index cfcd27074a..7cc89ad9b8 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml @@ -20,6 +20,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -29,7 +31,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -39,7 +41,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -50,9 +54,9 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFNvBVQx43PNOIf1dWnEUT5u5fA", + "id": "chatcmpl-ASYMT7913Sp58qhZqQgY7g7Ia2J4M", "object": "chat.completion", - "created": 1730680117, + "created": 1731368633, "model": "gpt-4o-mini-2024-07-18", "choices": [ { @@ -71,10 +75,14 @@ interactions: "completion_tokens": 12, "total_tokens": 24, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, "service_tier": "default", @@ -84,13 +92,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c2d0a5a9f98-SIN + - 8e1225a3f8e9ce65-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:37 GMT + - Mon, 11 Nov 2024 23:43:53 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -103,10 +111,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '697' - openai-organization: test_organization + - '825' + openai-organization: test_openai_org_id openai-processing-ms: - - '228' + - '431' openai-version: - '2020-10-01' strict-transport-security: @@ -120,11 +128,11 @@ interactions: x-ratelimit-remaining-tokens: - '199943' x-ratelimit-reset-requests: - - 13.724s + - 14.746s x-ratelimit-reset-tokens: - 16ms x-request-id: - - req_0ded46a4535c24c36ef58363b7538421 + - req_81e29a8992ea8001c0240bd990acf0ab status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml index 9518e41225..23828e98f4 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml @@ -17,6 +17,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -26,7 +28,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -36,7 +38,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -47,16 +51,16 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFO3w0cNVOphe5Lk9EaYyRaS2pm", + "id": "chatcmpl-ASYMUBq69UHDarAz2fsd0O50rv0r1", "object": "chat.completion", - "created": 1730680118, + "created": 1731368634, "model": "gpt-4o-mini-2024-07-18", "choices": [ { "index": 0, "message": { "role": "assistant", - "content": "This is a test.", + "content": "This is a test. How can I assist you further?", "refusal": null }, "logprobs": null, @@ -66,7 +70,7 @@ interactions: "index": 1, "message": { "role": "assistant", - "content": "This is a test! How can I assist you further?", + "content": "This is a test. How can I assist you further?", "refusal": null }, "logprobs": null, @@ -75,13 +79,17 @@ interactions: ], "usage": { "prompt_tokens": 12, - "completion_tokens": 17, - "total_tokens": 29, + "completion_tokens": 24, + "total_tokens": 36, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, "system_fingerprint": "fp_0ba0d124f1" @@ -90,13 +98,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c30beda3dd4-SIN + - 8e1225a91a253e53-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:38 GMT + - Mon, 11 Nov 2024 23:43:54 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -109,10 +117,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '872' - openai-organization: test_organization + - '1030' + openai-organization: test_openai_org_id openai-processing-ms: - - '261' + - '399' openai-version: - '2020-10-01' strict-transport-security: @@ -126,11 +134,11 @@ interactions: x-ratelimit-remaining-tokens: - '199962' x-ratelimit-reset-requests: - - 21.785s + - 22.564s x-ratelimit-reset-tokens: - 11ms x-request-id: - - req_86ab6a7a85f95e2a001cfeb89e0827b1 + - req_01290a92a1a3d787c7a00bb3836da597 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml index e587ce5a38..ea06ca5984 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml @@ -24,6 +24,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -33,7 +35,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -43,7 +45,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -53,237 +57,223 @@ interactions: response: body: string: |+ - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" For"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" To"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" get"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" most"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" capabilities"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" accurate"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" do"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" latest"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" not"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" up"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" include"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" accessing"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-date"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" please"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" recommend"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" reliable"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" checking"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" reliable"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" You"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" use"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Channel"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" search"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Acc"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" You"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" engine"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"u"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"Weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" service"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" immediate"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" voice"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" assistant"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" service"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" local"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" news"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" station"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" search"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Would"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"'s"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" online"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" some"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" If"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" tips"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" there's"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"'s"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" anything"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" conditions"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" where"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" else"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you'd"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" today"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" find"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" this"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"?"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" know"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" feel"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" free"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-APfFT3JSFkuTVECTo0DfULAD8vftU","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":111,"total_tokens":137,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":104,"total_tokens":130,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} data: [DONE] @@ -291,13 +281,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c55783bce06-SIN + - 8e1225d0fa1481e4-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Mon, 04 Nov 2024 00:28:44 GMT + - Mon, 11 Nov 2024 23:44:00 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -309,9 +299,9 @@ interactions: - X-Request-ID alt-svc: - h3=":443"; ma=86400 - openai-organization: test_organization + openai-organization: test_openai_org_id openai-processing-ms: - - '127' + - '176' openai-version: - '2020-10-01' strict-transport-security: @@ -325,11 +315,11 @@ interactions: x-ratelimit-remaining-tokens: - '199945' x-ratelimit-reset-requests: - - 59.105s + - 59.369s x-ratelimit-reset-tokens: - 16ms x-request-id: - - req_4d50387aa59e08f2dc486aa5c62613f5 + - req_892a6021b1acc00254d8ff80adcd82fb status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml index 8989eb9cfa..951aa52259 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml @@ -46,6 +46,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -55,7 +57,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -65,7 +67,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -75,41 +79,41 @@ interactions: response: body: string: |+ - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_H7ADtKo1DKIzNyrCSBt1jKdw","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_j7L00WV19wwQCvKOIVZewXZm","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_Dmv04Iin9mOpBKWSwdb5DbpS","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_sAIOI3dvcd1YMsEqD8DI3l8B","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - data: {"id":"chatcmpl-APfFYyp9joT2Wwh01iYvcm6iDYtV3","object":"chat.completion.chunk","created":1730680128,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} data: [DONE] @@ -117,13 +121,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c715fd66beb-SIN + - 8e1225e40bed40c8-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Mon, 04 Nov 2024 00:28:49 GMT + - Mon, 11 Nov 2024 23:44:04 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -135,9 +139,9 @@ interactions: - X-Request-ID alt-svc: - h3=":443"; ma=86400 - openai-organization: test_organization + openai-organization: test_openai_org_id openai-processing-ms: - - '647' + - '1225' openai-version: - '2020-10-01' strict-transport-security: @@ -151,11 +155,11 @@ interactions: x-ratelimit-remaining-tokens: - '199961' x-ratelimit-reset-requests: - - 1m11.934s + - 1m13.588s x-ratelimit-reset-tokens: - 11ms x-request-id: - - req_66ecdeba3a9e89bbc2aa60243fb1fdfb + - req_102cd878d03c1cec0c12b95f928d03ee status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml index c39facccc5..d42ac86e37 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml @@ -46,6 +46,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -55,7 +57,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -65,7 +67,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -75,41 +79,41 @@ interactions: response: body: string: |+ - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_CqwFQqzbiNttzDzEXiUitRos","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_fHCjJqt9Pysde6vcJcvbXGBx","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_SGVgEhhsqfE7s6MOHSXwKSGG","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_3J9foSw3CUb48lrqIXoTky6U","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - data: {"id":"chatcmpl-APfFVrgZUKVR18p3BuIQN3OYWjFIM","object":"chat.completion.chunk","created":1730680125,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} data: [DONE] @@ -117,13 +121,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c5d48f0ce22-SIN + - 8e1225d8af0c3d93-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Mon, 04 Nov 2024 00:28:48 GMT + - Mon, 11 Nov 2024 23:44:03 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -135,9 +139,9 @@ interactions: - X-Request-ID alt-svc: - h3=":443"; ma=86400 - openai-organization: test_organization + openai-organization: test_openai_org_id openai-processing-ms: - - '2886' + - '1399' openai-version: - '2020-10-01' strict-transport-security: @@ -151,11 +155,11 @@ interactions: x-ratelimit-remaining-tokens: - '199961' x-ratelimit-reset-requests: - - 1m6.499s + - 1m6.779s x-ratelimit-reset-tokens: - 11ms x-request-id: - - req_c887b8540fec8e4eadca5d56c78cc4e1 + - req_d745d48bf030ac78e4790ee49848d05f status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml index 713ea762e0..db482a440c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml @@ -19,6 +19,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -28,7 +30,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -38,7 +40,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -48,21 +52,21 @@ interactions: response: body: string: |+ - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"This"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\""},"logprobs":null,"finish_reason":null}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - data: {"id":"chatcmpl-APfFSQXvyhxafsCMim55E7utaYINv","object":"chat.completion.chunk","created":1730680122,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0}}} + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} data: [DONE] @@ -70,13 +74,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c4b99b74927-SIN + - 8e1225c87b273e53-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Mon, 04 Nov 2024 00:28:42 GMT + - Mon, 11 Nov 2024 23:43:59 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -88,9 +92,9 @@ interactions: - X-Request-ID alt-svc: - h3=":443"; ma=86400 - openai-organization: test_organization + openai-organization: test_openai_org_id openai-processing-ms: - - '157' + - '207' openai-version: - '2020-10-01' strict-transport-security: @@ -108,7 +112,7 @@ interactions: x-ratelimit-reset-tokens: - 132ms x-request-id: - - req_72de20dac77a9535e3f47a6ec3a39ddc + - req_c367cf360ee88481fb7cd6c5d45bf9dc status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml index bec0658770..4d56e51a06 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml @@ -16,6 +16,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -25,7 +27,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -35,7 +37,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -45,19 +49,19 @@ interactions: response: body: string: |+ - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} - data: {"id":"chatcmpl-APfFTxI7bvaTTeQd32CHwpV6GKo7x","object":"chat.completion.chunk","created":1730680123,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} data: [DONE] @@ -65,13 +69,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c505e24cdf2-SIN + - 8e1225ccb98e823b-SIN Connection: - keep-alive Content-Type: - text/event-stream; charset=utf-8 Date: - - Mon, 04 Nov 2024 00:28:43 GMT + - Mon, 11 Nov 2024 23:43:59 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -83,9 +87,9 @@ interactions: - X-Request-ID alt-svc: - h3=":443"; ma=86400 - openai-organization: test_organization + openai-organization: test_openai_org_id openai-processing-ms: - - '269' + - '205' openai-version: - '2020-10-01' strict-transport-security: @@ -99,11 +103,11 @@ interactions: x-ratelimit-remaining-tokens: - '9978' x-ratelimit-reset-requests: - - 16.502s + - 16.601s x-ratelimit-reset-tokens: - 132ms x-request-id: - - req_04c174debe2eace86b1e2777d7ac7265 + - req_d13225164a822ec3ebab5591ed0b6d6a status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml index b4d5acca4a..4731f202c3 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml @@ -42,6 +42,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -51,7 +53,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -61,7 +63,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -72,9 +76,9 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFQZB7CuqkWhGyMZegJZRX2Mqv7", + "id": "chatcmpl-ASYMW6w3m9qqpHUVhYTbQbw61zMqA", "object": "chat.completion", - "created": 1730680120, + "created": 1731368636, "model": "gpt-4o-mini-2024-07-18", "choices": [ { @@ -84,7 +88,7 @@ interactions: "content": null, "tool_calls": [ { - "id": "call_SBoEJuTov3qHLothPvvgZyO6", + "id": "call_eqbDFUdPqay2WjsSzZEiAn0U", "type": "function", "function": { "name": "get_current_weather", @@ -92,7 +96,7 @@ interactions: } }, { - "id": "call_2nL8HxSquLkKxpTENiZ17ynv", + "id": "call_tn3sgasg6GaftTdancBYJNJN", "type": "function", "function": { "name": "get_current_weather", @@ -111,10 +115,14 @@ interactions: "completion_tokens": 51, "total_tokens": 126, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, "system_fingerprint": "fp_0ba0d124f1" @@ -123,13 +131,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c3f4ba7ce35-SIN + - 8e1225ba6a3440b0-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:41 GMT + - Mon, 11 Nov 2024 23:43:57 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -142,10 +150,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '1180' - openai-organization: test_organization + - '1308' + openai-organization: test_openai_org_id openai-processing-ms: - - '984' + - '761' openai-version: - '2020-10-01' strict-transport-security: @@ -159,11 +167,11 @@ interactions: x-ratelimit-remaining-tokens: - '199961' x-ratelimit-reset-requests: - - 45.38s + - 45.694s x-ratelimit-reset-tokens: - 11ms x-request-id: - - req_af3dca7532583ed0a68645314bcc9be0 + - req_f98710550c77b43865572fc1a7a0bc53 status: code: 200 message: OK @@ -183,7 +191,7 @@ interactions: "role": "assistant", "tool_calls": [ { - "id": "call_SBoEJuTov3qHLothPvvgZyO6", + "id": "call_eqbDFUdPqay2WjsSzZEiAn0U", "function": { "arguments": "{\"location\": \"Seattle, WA\"}", "name": "get_current_weather" @@ -191,7 +199,7 @@ interactions: "type": "function" }, { - "id": "call_2nL8HxSquLkKxpTENiZ17ynv", + "id": "call_tn3sgasg6GaftTdancBYJNJN", "function": { "arguments": "{\"location\": \"San Francisco, CA\"}", "name": "get_current_weather" @@ -203,12 +211,12 @@ interactions: { "role": "tool", "content": "50 degrees and raining", - "tool_call_id": "call_SBoEJuTov3qHLothPvvgZyO6" + "tool_call_id": "call_eqbDFUdPqay2WjsSzZEiAn0U" }, { "role": "tool", "content": "70 degrees and sunny", - "tool_call_id": "call_2nL8HxSquLkKxpTENiZ17ynv" + "tool_call_id": "call_tn3sgasg6GaftTdancBYJNJN" } ], "model": "gpt-4o-mini" @@ -218,6 +226,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -225,12 +235,11 @@ interactions: content-type: - application/json cookie: - - __cf_bm=moy9FTa50Ug99_ZQaP2atn.PgzKoQyF7pvWqG_CIf54-1730680121-1.0.1.1-mczyecbBSU5hWl8uat1lcU6ya1g6MY.Oso_vHVilj7O8C2RJrObTEyzD5DAMphUCFqBYVGHMurXg16CMssvuNw; - _cfuvid=FpMMQOb0sz4wVuQI7b1RY2KJKVNyHctKOqsWAL4tph0-1730680121454-0.0.1.1-604800000 + - test_cookie host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -240,7 +249,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -251,16 +262,16 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFRbb22UJc07TGY9KcrrWO5fs9c", + "id": "chatcmpl-ASYMYObbcUyZ77rbvypWmcZPIVSf1", "object": "chat.completion", - "created": 1730680121, + "created": 1731368638, "model": "gpt-4o-mini-2024-07-18", "choices": [ { "index": 0, "message": { "role": "assistant", - "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", + "content": "Today, the weather in Seattle is 50 degrees and raining, while San Francisco is enjoying 70 degrees and sunny weather.", "refusal": null }, "logprobs": null, @@ -272,10 +283,14 @@ interactions: "completion_tokens": 25, "total_tokens": 124, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, "system_fingerprint": "fp_0ba0d124f1" @@ -284,13 +299,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c473cc4ce35-SIN + - 8e1225c12f6340b0-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:42 GMT + - Mon, 11 Nov 2024 23:43:58 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -303,10 +318,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '731' - openai-organization: test_organization + - '870' + openai-organization: test_openai_org_id openai-processing-ms: - - '380' + - '722' openai-version: - '2020-10-01' strict-transport-security: @@ -318,13 +333,13 @@ interactions: x-ratelimit-remaining-requests: - '9993' x-ratelimit-remaining-tokens: - - '199947' + - '199948' x-ratelimit-reset-requests: - - 52.749s + - 53.254s x-ratelimit-reset-tokens: - 15ms x-request-id: - - req_f56de3d8b168900542a01b971b367a9f + - req_2bb3d10a2a75f5d64a24aef595a0d8dd status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml index fbf1abd640..6ceb618d24 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml @@ -42,6 +42,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -51,7 +53,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -61,7 +63,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -72,9 +76,9 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFOuWLsYvVpZYqENRo9rKnifNdD", + "id": "chatcmpl-ASYMU9Ntix7ePttk0MSuerJstef6U", "object": "chat.completion", - "created": 1730680118, + "created": 1731368634, "model": "gpt-4o-mini-2024-07-18", "choices": [ { @@ -84,7 +88,7 @@ interactions: "content": null, "tool_calls": [ { - "id": "call_6YvurIMPOgMo2q6V6KGJDA6g", + "id": "call_JpNb8OiAkbIbHzDggfpdDHpi", "type": "function", "function": { "name": "get_current_weather", @@ -92,7 +96,7 @@ interactions: } }, { - "id": "call_QSiqEulo25M3NtTLVbMGqY91", + "id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ", "type": "function", "function": { "name": "get_current_weather", @@ -111,10 +115,14 @@ interactions: "completion_tokens": 51, "total_tokens": 126, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, "system_fingerprint": "fp_0ba0d124f1" @@ -123,13 +131,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c349cb38bcb-SIN + - 8e1225ae3ea281e4-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:39 GMT + - Mon, 11 Nov 2024 23:43:55 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -142,10 +150,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '1180' - openai-organization: test_organization + - '1308' + openai-organization: test_openai_org_id openai-processing-ms: - - '631' + - '748' openai-version: - '2020-10-01' strict-transport-security: @@ -159,11 +167,11 @@ interactions: x-ratelimit-remaining-tokens: - '199961' x-ratelimit-reset-requests: - - 29.791s + - 30.375s x-ratelimit-reset-tokens: - 11ms x-request-id: - - req_a121f023915b3c4a2ca2415663e54dd8 + - req_a0c3b432eb349a35b6d8dde6e01451e4 status: code: 200 message: OK @@ -183,7 +191,7 @@ interactions: "role": "assistant", "tool_calls": [ { - "id": "call_6YvurIMPOgMo2q6V6KGJDA6g", + "id": "call_JpNb8OiAkbIbHzDggfpdDHpi", "function": { "arguments": "{\"location\": \"Seattle, WA\"}", "name": "get_current_weather" @@ -191,7 +199,7 @@ interactions: "type": "function" }, { - "id": "call_QSiqEulo25M3NtTLVbMGqY91", + "id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ", "function": { "arguments": "{\"location\": \"San Francisco, CA\"}", "name": "get_current_weather" @@ -203,12 +211,12 @@ interactions: { "role": "tool", "content": "50 degrees and raining", - "tool_call_id": "call_6YvurIMPOgMo2q6V6KGJDA6g" + "tool_call_id": "call_JpNb8OiAkbIbHzDggfpdDHpi" }, { "role": "tool", "content": "70 degrees and sunny", - "tool_call_id": "call_QSiqEulo25M3NtTLVbMGqY91" + "tool_call_id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ" } ], "model": "gpt-4o-mini" @@ -218,6 +226,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -225,12 +235,11 @@ interactions: content-type: - application/json cookie: - - __cf_bm=Fyf0tyDn1mwa_82CHRs1nppW_PehJkXoYvNM4ZjPbXY-1730680119-1.0.1.1-yjV4_xtp96WEMEexlzeQsjZfgRKwMtgjBU5ysQffHMNwXbTqmZdE_pCTtQTmJ97xP37rkkAHdzC7O8661FKZ9A; - _cfuvid=WLvZI_.UlWSOmjux14bNggQUKClph3WCDG.6pjaRbjI-1730680119424-0.0.1.1-604800000 + - test_cookie host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -240,7 +249,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -251,9 +262,9 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFP2ZYRsgIvw0HuTVbYFDxFs7Si", + "id": "chatcmpl-ASYMVzdmBGDbUoHFmt6R16tdtZUzR", "object": "chat.completion", - "created": 1730680119, + "created": 1731368635, "model": "gpt-4o-mini-2024-07-18", "choices": [ { @@ -272,25 +283,29 @@ interactions: "completion_tokens": 25, "total_tokens": 124, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, - "system_fingerprint": "fp_0ba0d124f1" + "system_fingerprint": "fp_9b78b61c52" } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c3ad9138bcb-SIN + - 8e1225b4cbf581e4-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:40 GMT + - Mon, 11 Nov 2024 23:43:56 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -303,10 +318,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '731' - openai-organization: test_organization + - '859' + openai-organization: test_openai_org_id openai-processing-ms: - - '390' + - '531' openai-version: - '2020-10-01' strict-transport-security: @@ -320,11 +335,11 @@ interactions: x-ratelimit-remaining-tokens: - '199947' x-ratelimit-reset-requests: - - 37.448s + - 37.973s x-ratelimit-reset-tokens: - 15ms x-request-id: - - req_525d3b9301fff00a98647143a9c26b6f + - req_22b79d2dddb920f55e33727d06724978 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml index bb61c001fb..2abb443fe3 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -16,6 +16,8 @@ interactions: - application/json accept-encoding: - gzip, deflate + authorization: + - Bearer test_openai_api_key connection: - keep-alive content-length: @@ -25,7 +27,7 @@ interactions: host: - api.openai.com user-agent: - - OpenAI/Python 1.26.0 + - OpenAI/Python 1.54.3 x-stainless-arch: - arm64 x-stainless-async: @@ -35,7 +37,9 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.26.0 + - 1.54.3 + x-stainless-retry-count: + - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -46,16 +50,16 @@ interactions: body: string: |- { - "id": "chatcmpl-APfFJNBzCZVUpMJMK5KBhu4D6yVAc", + "id": "chatcmpl-ASYMQRl3A3DXL9FWCK9tnGRcKIO7q", "object": "chat.completion", - "created": 1730680113, + "created": 1731368630, "model": "gpt-4o-mini-2024-07-18", "choices": [ { "index": 0, "message": { "role": "assistant", - "content": "This is a test! How can I assist you today?", + "content": "This is a test.", "refusal": null }, "logprobs": null, @@ -64,13 +68,17 @@ interactions: ], "usage": { "prompt_tokens": 12, - "completion_tokens": 12, - "total_tokens": 24, + "completion_tokens": 5, + "total_tokens": 17, "prompt_tokens_details": { - "cached_tokens": 0 + "cached_tokens": 0, + "audio_tokens": 0 }, "completion_tokens_details": { - "reasoning_tokens": 0 + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 } }, "system_fingerprint": "fp_0ba0d124f1" @@ -79,13 +87,13 @@ interactions: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8dd07c16eae44a1d-SIN + - 8e122593ff368bc8-SIN Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 04 Nov 2024 00:28:34 GMT + - Mon, 11 Nov 2024 23:43:50 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -98,10 +106,10 @@ interactions: alt-svc: - h3=":443"; ma=86400 content-length: - - '666' - openai-organization: test_organization + - '765' + openai-organization: test_openai_org_id openai-processing-ms: - - '732' + - '287' openai-version: - '2020-10-01' strict-transport-security: @@ -119,7 +127,7 @@ interactions: x-ratelimit-reset-tokens: - 6ms x-request-id: - - req_0bb3c9da7d953e477d1947130d2cf1df + - req_58cff97afd0e7c0bba910ccf0b044a6f status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 899b2f122c..e5c7bca359 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -55,7 +55,7 @@ def fixture_event_logger_provider(log_exporter): @pytest.fixture(autouse=True) def environment(): if not os.getenv("OPENAI_API_KEY"): - os.environ["OPENAI_API_KEY"] = "test-api-key" + os.environ["OPENAI_API_KEY"] = "test_openai_api_key" @pytest.fixture @@ -66,7 +66,12 @@ def openai_client(): @pytest.fixture(scope="module") def vcr_config(): return { - "filter_headers": ["authorization", "api-key"], + "filter_headers": [ + ("cookie", "test_cookie"), + ("authorization", "Bearer test_openai_api_key"), + ("openai-organization", "test_openai_org_id"), + ("openai-project", "test_openai_project_id"), + ], "decode_compressed_response": True, "before_record_response": scrub_response_headers, } @@ -171,6 +176,6 @@ def scrub_response_headers(response): """ This scrubs sensitive response headers. Note they are case-sensitive! """ - response["headers"]["openai-organization"] = "test_organization" + response["headers"]["openai-organization"] = "test_openai_org_id" response["headers"]["Set-Cookie"] = "test_set_cookie" return response From e3ba54b95c68a0b56daccb80cd57f1987714ddf4 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 12 Nov 2024 15:13:42 -0800 Subject: [PATCH 232/335] Add openai instrumentation to opentelemetry-bootstrap (#2996) --- CHANGELOG.md | 2 ++ .../pyproject.toml | 2 +- .../opentelemetry/instrumentation/bootstrap_gen.py | 4 ++++ scripts/otel_packaging.py | 11 ++++++++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6be2429f06..24760db6c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-sqlalchemy` Update unit tests to run with SQLALchemy 2 ([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976)) + - Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap` + ([#2996](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2996)) ### Fixed diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index eddd85e5f0..e28611d0c5 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "openai >= 1.0.0", + "openai >= 1.26.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 2e7b5532f3..6b7eae6b00 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -16,6 +16,10 @@ # RUN `python scripts/generate_instrumentation_bootstrap.py` TO REGENERATE. libraries = [ + { + "library": "openai >= 1.26.0", + "instrumentation": "opentelemetry-instrumentation-openai-v2==2.1b0.dev", + }, { "library": "aio_pika >= 7.2.0, < 10.0.0", "instrumentation": "opentelemetry-instrumentation-aio-pika==0.50b0.dev", diff --git a/scripts/otel_packaging.py b/scripts/otel_packaging.py index 2f42e44189..3b09dd87eb 100644 --- a/scripts/otel_packaging.py +++ b/scripts/otel_packaging.py @@ -21,14 +21,23 @@ scripts_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.dirname(scripts_path) instrumentations_path = os.path.join(root_path, "instrumentation") +genai_instrumentations_path = os.path.join(root_path, "instrumentation-genai") def get_instrumentation_packages(): - for pkg in sorted(os.listdir(instrumentations_path)): + pkg_paths = [] + for pkg in os.listdir(instrumentations_path): pkg_path = os.path.join(instrumentations_path, pkg) if not os.path.isdir(pkg_path): continue + pkg_paths.append(pkg_path) + for pkg in os.listdir(genai_instrumentations_path): + pkg_path = os.path.join(genai_instrumentations_path, pkg) + if not os.path.isdir(pkg_path): + continue + pkg_paths.append(pkg_path) + for pkg_path in sorted(pkg_paths): try: version = subprocess.check_output( "hatch version", From a6e4a0ca43d329928d02bd51ba175339e4e40ad1 Mon Sep 17 00:00:00 2001 From: Ali Waleed Date: Thu, 14 Nov 2024 18:53:27 +0200 Subject: [PATCH 233/335] Add Support for `Async` openai instrumentation (#2984) --- .github/component_owners.yml | 1 + .../CHANGELOG.md | 2 + .../instrumentation/openai_v2/__init__.py | 11 +- .../instrumentation/openai_v2/patch.py | 86 +- .../instrumentation/openai_v2/utils.py | 21 +- .../test-requirements-0.txt | 1 + .../test-requirements-1.txt | 1 + .../test_async_chat_completion_404.yaml | 89 ++ ...st_async_chat_completion_extra_params.yaml | 137 +++ ...sync_chat_completion_multiple_choices.yaml | 143 +++ ...completion_multiple_choices_streaming.yaml | 382 ++++++++ ...n_multiple_tools_streaming_no_content.yaml | 164 ++++ ...multiple_tools_streaming_with_content.yaml | 164 ++++ .../test_async_chat_completion_streaming.yaml | 117 +++ ...hat_completion_streaming_not_complete.yaml | 112 +++ ...chat_completion_tool_calls_no_content.yaml | 342 +++++++ ...at_completion_tool_calls_with_content.yaml | 342 +++++++ ...st_async_chat_completion_with_content.yaml | 132 +++ .../tests/conftest.py | 7 +- .../tests/test_async_chat_completions.py | 847 ++++++++++++++++++ 20 files changed, 3081 insertions(+), 20 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_404.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 1e89d59567..5cbb6aa402 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -73,4 +73,5 @@ components: - lzchen - gyliu513 - nirga + - alizenhom - codefromthecrypt diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 2fdeeea74f..07b10615c1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Support for `AsyncOpenAI/AsyncCompletions` ([#2984](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2984)) + ## Version 2.0b0 (2024-11-08) - Use generic `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` environment variable diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py index e8a782e404..ee3bbfdb73 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -52,7 +52,7 @@ from opentelemetry.semconv.schemas import Schemas from opentelemetry.trace import get_tracer -from .patch import chat_completions_create +from .patch import async_chat_completions_create, chat_completions_create class OpenAIInstrumentor(BaseInstrumentor): @@ -84,7 +84,16 @@ def _instrument(self, **kwargs): ), ) + wrap_function_wrapper( + module="openai.resources.chat.completions", + name="AsyncCompletions.create", + wrapper=async_chat_completions_create( + tracer, event_logger, is_content_enabled() + ), + ) + def _uninstrument(self, **kwargs): import openai # pylint: disable=import-outside-toplevel unwrap(openai.resources.chat.completions.Completions, "create") + unwrap(openai.resources.chat.completions.AsyncCompletions, "create") diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 8540bff219..cd284473ce 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -21,15 +21,12 @@ from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) -from opentelemetry.semconv.attributes import ( - error_attributes as ErrorAttributes, -) from opentelemetry.trace import Span, SpanKind, Tracer -from opentelemetry.trace.status import Status, StatusCode from .utils import ( choice_to_event, get_llm_request_attributes, + handle_span_exception, is_streaming, message_to_event, set_span_attribute, @@ -72,12 +69,49 @@ def traced_method(wrapped, instance, args, kwargs): return result except Exception as error: - span.set_status(Status(StatusCode.ERROR, str(error))) + handle_span_exception(span, error) + raise + + return traced_method + + +def async_chat_completions_create( + tracer: Tracer, event_logger: EventLogger, capture_content: bool +): + """Wrap the `create` method of the `AsyncChatCompletion` class to trace it.""" + + async def traced_method(wrapped, instance, args, kwargs): + span_attributes = {**get_llm_request_attributes(kwargs, instance)} + + span_name = f"{span_attributes[GenAIAttributes.GEN_AI_OPERATION_NAME]} {span_attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL]}" + with tracer.start_as_current_span( + name=span_name, + kind=SpanKind.CLIENT, + attributes=span_attributes, + end_on_exit=False, + ) as span: + if span.is_recording(): + for message in kwargs.get("messages", []): + event_logger.emit( + message_to_event(message, capture_content) + ) + + try: + result = await wrapped(*args, **kwargs) + if is_streaming(kwargs): + return StreamWrapper( + result, span, event_logger, capture_content + ) + if span.is_recording(): - span.set_attribute( - ErrorAttributes.ERROR_TYPE, type(error).__qualname__ + _set_response_attributes( + span, result, event_logger, capture_content ) span.end() + return result + + except Exception as error: + handle_span_exception(span, error) raise return traced_method @@ -286,10 +320,19 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): try: if exc_type is not None: - self.span.set_status(Status(StatusCode.ERROR, str(exc_val))) - self.span.set_attribute( - ErrorAttributes.ERROR_TYPE, exc_type.__qualname__ - ) + handle_span_exception(self.span, exc_val) + finally: + self.cleanup() + return False # Propagate the exception + + async def __aenter__(self): + self.setup() + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + try: + if exc_type is not None: + handle_span_exception(self.span, exc_val) finally: self.cleanup() return False # Propagate the exception @@ -301,6 +344,9 @@ def close(self): def __iter__(self): return self + def __aiter__(self): + return self + def __next__(self): try: chunk = next(self.stream) @@ -310,10 +356,20 @@ def __next__(self): self.cleanup() raise except Exception as error: - self.span.set_status(Status(StatusCode.ERROR, str(error))) - self.span.set_attribute( - ErrorAttributes.ERROR_TYPE, type(error).__qualname__ - ) + handle_span_exception(self.span, error) + self.cleanup() + raise + + async def __anext__(self): + try: + chunk = await self.stream.__anext__() + self.process_chunk(chunk) + return chunk + except StopAsyncIteration: + self.cleanup() + raise + except Exception as error: + handle_span_exception(self.span, error) self.cleanup() raise diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index a3a2d317ce..cf920c17ee 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -26,6 +26,10 @@ from opentelemetry.semconv._incubating.attributes import ( server_attributes as ServerAttributes, ) +from opentelemetry.semconv.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.trace.status import Status, StatusCode OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = ( "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" @@ -138,9 +142,11 @@ def choice_to_event(choice, capture_content): if choice.message: message = { - "role": choice.message.role - if choice.message and choice.message.role - else None + "role": ( + choice.message.role + if choice.message and choice.message.role + else None + ) } tool_calls = extract_tool_calls(choice.message, capture_content) if tool_calls: @@ -210,3 +216,12 @@ def get_llm_request_attributes( # filter out None values return {k: v for k, v in attributes.items() if v is not None} + + +def handle_span_exception(span, error): + span.set_status(Status(StatusCode.ERROR, str(error))) + if span.is_recording(): + span.set_attribute( + ErrorAttributes.ERROR_TYPE, type(error).__qualname__ + ) + span.end() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt index 7a15734872..5e1693b69a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt @@ -5,6 +5,7 @@ importlib-metadata==6.11.0 packaging==24.0 pytest==7.4.4 pytest-vcr==1.0.2 +pytest-asyncio==0.21.0 wrapt==1.16.0 opentelemetry-api==1.28 # when updating, also update in pyproject.toml opentelemetry-sdk==1.28 # when updating, also update in pyproject.toml diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt index ded849c8ee..618410edd3 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt @@ -5,6 +5,7 @@ importlib-metadata==6.11.0 packaging==24.0 pytest==7.4.4 pytest-vcr==1.0.2 +pytest-asyncio==0.21.0 wrapt==1.16.0 # test with the latest version of opentelemetry-api, sdk, and semantic conventions diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_404.yaml new file mode 100644 index 0000000000..e055e68f20 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_404.yaml @@ -0,0 +1,89 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "this-model-does-not-exist" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '103' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "error": { + "message": "The model `this-model-does-not-exist` does not exist or you do not have access to it.", + "type": "invalid_request_error", + "param": null, + "code": "model_not_found" + } + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80827a861852-MRS + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:01 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '231' + openai-organization: test_openai_org_id + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Origin + x-request-id: + - req_5cf06a7fabd45ebe21ee38c14c5b2f76 + status: + code: 404 + message: Not Found +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml new file mode 100644 index 0000000000..3d13c9344e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml @@ -0,0 +1,137 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "max_tokens": 50, + "seed": 42, + "stream": false, + "temperature": 0.5, + "service_tier": "default" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '183' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9WMTAMZY4O1EImv3csZa6Ch7KI", + "object": "chat.completion", + "created": 1731456242, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a8088f867e167-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:02 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '825' + openai-organization: test_openai_org_id + openai-processing-ms: + - '488' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999943' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_6df08d6267415e8f5db3628a6757edad + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml new file mode 100644 index 0000000000..1404b8163a --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml @@ -0,0 +1,143 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '114' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9XLlMmT7H3cf50dNTesHDBDwX5", + "object": "chat.completion", + "created": 1731456243, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + }, + { + "index": 1, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 10, + "total_tokens": 22, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a808f6d8e0d8b-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:04 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '970' + openai-organization: test_openai_org_id + openai-processing-ms: + - '306' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999962' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_1317908e0f9b73276b57d4e171c533ea + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml new file mode 100644 index 0000000000..4bca03a9e8 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml @@ -0,0 +1,382 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": true, + "stream_options": { + "include_usage": true + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '254' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" was"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" only"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" last"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" extends"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" until"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updated"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" October"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" October"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" access"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" access"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" visiting"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" mobile"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" most"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" If"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" accurate"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" need"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" up"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" historical"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" general"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" climate"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" those"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" cities"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" feel"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" free"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-date"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":133,"total_tokens":159,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80ceac3ce19a-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:13 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '126' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999945' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_5dd8b6845db59fa55cf226eda1f5a2c6 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml new file mode 100644 index 0000000000..19319de476 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml @@ -0,0 +1,164 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_hqkL24CLEwnniv4GDrjk14Iu","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_0s1enkFttXjIR7ozHoGMcnUu","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80e4cfb00d86-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:19 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '1597' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_487aef2347cb4d1f97077c488dd93628 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml new file mode 100644 index 0000000000..a026912ee1 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml @@ -0,0 +1,164 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_oJL2dc4GjWVxqBtWlGLwjbsR","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ON3lp1OWsbw2obNRD43KVDp6","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80d8efb9e1c8-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:16 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '1162' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_0b6729aef347cecd61ba3b7b7a8d4719 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming.yaml new file mode 100644 index 0000000000..efffcd7423 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming.yaml @@ -0,0 +1,117 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true, + "stream_options": { + "include_usage": true + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '142' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80bd2f31e1e5-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:11 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '196' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '1000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '999977' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 1ms + x-request-id: + - req_cc9204ae23338b130df11c8c5b5f31af + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml new file mode 100644 index 0000000000..9ef5613d17 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml @@ -0,0 +1,112 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '99' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80c54d00e288-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:12 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '283' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '1000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '999977' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 1ms + x-request-id: + - req_e9e4ea6fd060391e8cc8cfea78ad9a15 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml new file mode 100644 index 0000000000..053e271d45 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml @@ -0,0 +1,342 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9bJqWatpvCC0YMsYRcTSIiXoxk", + "object": "chat.completion", + "created": 1731456247, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_vwOezSsB5j9ei1SSMlZjqx7g", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_LzeIYcKhHnVF60u4LmBpT1tv", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80a9f8fbe1c9-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:08 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1308' + openai-organization: test_openai_org_id + openai-processing-ms: + - '808' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_f1b9b75e4a73b542c9b1b992cd52c66f + status: + code: 200 + message: OK +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_vwOezSsB5j9ei1SSMlZjqx7g", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_LzeIYcKhHnVF60u4LmBpT1tv", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_vwOezSsB5j9ei1SSMlZjqx7g" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_LzeIYcKhHnVF60u4LmBpT1tv" + } + ], + "model": "gpt-4o-mini" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_cookie + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9dfXfIwGCZgeWzDTbCh0FuU9kh", + "object": "chat.completion", + "created": 1731456249, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 25, + "total_tokens": 124, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80b3baade1c9-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:10 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '859' + openai-organization: test_openai_org_id + openai-processing-ms: + - '972' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999948' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_754e6b59f1d3da727e2210e3d8c56243 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml new file mode 100644 index 0000000000..ebebb20603 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml @@ -0,0 +1,342 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9ZqgNAOJAOLYMgdmxouatKXJlk", + "object": "chat.completion", + "created": 1731456245, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_O8NOz8VlxosSASEsOY7LDUcP", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_3m7cyuckijnpiWr6tq0Tl8Mg", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a8098ac5ae167-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:06 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1308' + openai-organization: test_openai_org_id + openai-processing-ms: + - '937' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_3cd7152d2c8c10b4f354b27165f6c2b5 + status: + code: 200 + message: OK +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_O8NOz8VlxosSASEsOY7LDUcP", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_3m7cyuckijnpiWr6tq0Tl8Mg", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_O8NOz8VlxosSASEsOY7LDUcP" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_3m7cyuckijnpiWr6tq0Tl8Mg" + } + ], + "model": "gpt-4o-mini" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_cookie + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9aQnGndy04lqKoPRagym1eEaQK", + "object": "chat.completion", + "created": 1731456246, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, Seattle is experiencing 50 degrees and raining, while San Francisco has a pleasant 70 degrees and sunny weather.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 24, + "total_tokens": 123, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_f59a81427f" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80a39c71e167-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:07 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '871' + openai-organization: test_openai_org_id + openai-processing-ms: + - '477' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999948' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_193c74758ea30e77e55afe931e89fd6c + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_with_content.yaml new file mode 100644 index 0000000000..61ec4a646e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_with_content.yaml @@ -0,0 +1,132 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9R2E7Yhb2e7bj4Xl0qm9s3J42Y", + "object": "chat.completion", + "created": 1731456237, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80679a8311a6-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:03:58 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '796' + openai-organization: test_openai_org_id + openai-processing-ms: + - '359' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999978' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_41ea134c1fc450d4ca4cf8d0c6a7c53a + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index e5c7bca359..7ff7e46777 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -5,7 +5,7 @@ import pytest import yaml -from openai import OpenAI +from openai import AsyncOpenAI, OpenAI from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor from opentelemetry.instrumentation.openai_v2.utils import ( @@ -63,6 +63,11 @@ def openai_client(): return OpenAI() +@pytest.fixture +def async_openai_client(): + return AsyncOpenAI() + + @pytest.fixture(scope="module") def vcr_config(): return { diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py new file mode 100644 index 0000000000..1c4b3cb7dd --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py @@ -0,0 +1,847 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# pylint: disable=too-many-locals + +from typing import Optional + +import pytest +from openai import APIConnectionError, AsyncOpenAI, NotFoundError +from openai.resources.chat.completions import ChatCompletion + +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.semconv._incubating.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + event_attributes as EventAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_with_content( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.asyncio() +async def test_async_chat_completion_bad_endpoint( + span_exporter, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + client = AsyncOpenAI(base_url="http://localhost:4242") + + with pytest.raises(APIConnectionError): + await client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + timeout=0.1, + ) + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, server_address="localhost" + ) + assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] + assert ( + "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_404( + span_exporter, async_openai_client, instrument_no_content +): + llm_model_value = "this-model-does-not-exist" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + with pytest.raises(NotFoundError): + await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + ) + + spans = span_exporter.get_finished_spans() + + assert_all_attributes(spans[0], llm_model_value) + assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_extra_params( + span_exporter, async_openai_client, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + seed=42, + temperature=0.5, + max_tokens=50, + stream=False, + extra_body={"service_tier": "default"}, + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 + ) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + ) + assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] + == "default" + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_choices( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, n=2, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 # 1 user message + 2 choice messages + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[1].message.content, + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_tool_calls_with_content( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + await chat_completion_tool_call( + span_exporter, log_exporter, async_openai_client, True + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_tool_calls_no_content( + span_exporter, log_exporter, async_openai_client, instrument_no_content +): + await chat_completion_tool_call( + span_exporter, log_exporter, async_openai_client, False + ) + + +async def chat_completion_tool_call( + span_exporter, log_exporter, async_openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + ) + + # sanity check + assert "tool_calls" in response_0.choices[0].finish_reason + + # final request + messages_value.append( + { + "role": "assistant", + "tool_calls": response_0.choices[0].message.to_dict()[ + "tool_calls" + ], + } + ) + + tool_call_result_0 = { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": response_0.choices[0].message.tool_calls[0].id, + } + tool_call_result_1 = { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": response_0.choices[0].message.tool_calls[1].id, + } + + messages_value.append(tool_call_result_0) + messages_value.append(tool_call_result_1) + + response_1 = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value + ) + + # sanity check + assert "stop" in response_1.choices[0].finish_reason + + # validate both calls + spans = span_exporter.get_finished_spans() + assert len(spans) == 2 + assert_completion_attributes(spans[0], llm_model_value, response_0) + assert_completion_attributes(spans[1], llm_model_value, response_1) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 9 # 3 logs for first completion, 6 for second + + # call one + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + function_call_0 = {"name": "get_current_weather"} + function_call_1 = {"name": "get_current_weather"} + if expect_content: + function_call_0["arguments"] = ( + response_0.choices[0] + .message.tool_calls[0] + .function.arguments.replace("\n", "") + ) + function_call_1["arguments"] = ( + response_0.choices[0] + .message.tool_calls[1] + .function.arguments.replace("\n", "") + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": response_0.choices[0].message.tool_calls[0].id, + "type": "function", + "function": function_call_0, + }, + { + "id": response_0.choices[0].message.tool_calls[1].id, + "type": "function", + "function": function_call_1, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + # call two + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[3], "gen_ai.system.message", system_message, spans[1] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[4], "gen_ai.user.message", user_message, spans[1] + ) + + assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} + if not expect_content: + assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None + assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None + + assert_message_in_logs( + logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] + ) + + tool_message_0 = { + "id": tool_call_result_0["tool_call_id"], + "content": tool_call_result_0["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[6], "gen_ai.tool.message", tool_message_0, spans[1] + ) + + tool_message_1 = { + "id": tool_call_result_1["tool_call_id"], + "content": tool_call_result_1["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[7], "gen_ai.tool.message", tool_message_1, spans[1] + ) + + message = { + "role": "assistant", + "content": response_1.choices[0].message.content + if expect_content + else None, + } + choice = { + "index": 0, + "finish_reason": "stop", + "message": message, + } + assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_streaming( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + "stream_options": {"include_usage": True}, + } + + response_stream_usage = None + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = await async_openai_client.chat.completions.create(**kwargs) + async for chunk in response: + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_streaming_not_complete( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + } + + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = await async_openai_client.chat.completions.create(**kwargs) + idx = 0 + async for chunk in response: + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + if idx == 1: + # fake a stop + break + + if chunk.model: + response_stream_model = chunk.model + if chunk.id: + response_stream_id = chunk.id + idx += 1 + + response.close() + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, response_stream_id, response_stream_model + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "error", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_choices_streaming( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + n=2, + stream=True, + stream_options={"include_usage": True}, + ) + + # two strings for each choice + response_stream_result = ["", ""] + finish_reasons = ["", ""] + async for chunk in response_0: + if chunk.choices: + for choice in chunk.choices: + response_stream_result[choice.index] += ( + choice.delta.content or "" + ) + if choice.finish_reason: + finish_reasons[choice.index] = choice.finish_reason + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "stop" == finish_reasons[0] + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 4 + + system_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = { + "content": "What's the weather in Seattle and San Francisco today?" + } + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[0]), + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[1]), + }, + } + assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_tools_streaming_with_content( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + await async_chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, async_openai_client, True + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_tools_streaming_no_content( + span_exporter, log_exporter, async_openai_client, instrument_no_content +): + await async_chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, async_openai_client, False + ) + + +async def async_chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, async_openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + stream=True, + stream_options={"include_usage": True}, + ) + + finish_reason = None + # two tools + tool_names = ["", ""] + tool_call_ids = ["", ""] + tool_args = ["", ""] + async for chunk in response: + if chunk.choices: + if chunk.choices[0].finish_reason: + finish_reason = chunk.choices[0].finish_reason + for tool_call in chunk.choices[0].delta.tool_calls or []: + t_idx = tool_call.index + if tool_call.id: + tool_call_ids[t_idx] = tool_call.id + if tool_call.function: + if tool_call.function.arguments: + tool_args[t_idx] += tool_call.function.arguments + if tool_call.function.name: + tool_names[t_idx] = tool_call.function.name + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "tool_calls" == finish_reason + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 + + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": "What's the weather in Seattle and San Francisco today?"} + if expect_content + else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": tool_call_ids[0], + "type": "function", + "function": { + "name": tool_names[0], + "arguments": ( + tool_args[0].replace("\n", "") + if expect_content + else None + ), + }, + }, + { + "id": tool_call_ids[1], + "type": "function", + "function": { + "name": tool_names[1], + "arguments": ( + tool_args[1].replace("\n", "") + if expect_content + else None + ), + }, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + +def assert_message_in_logs(log, event_name, expected_content, parent_span): + assert log.log_record.attributes[EventAttributes.EVENT_NAME] == event_name + assert ( + log.log_record.attributes[GenAIAttributes.GEN_AI_SYSTEM] + == GenAIAttributes.GenAiSystemValues.OPENAI.value + ) + + if not expected_content: + assert not log.log_record.body + else: + assert log.log_record.body + assert dict(log.log_record.body) == remove_none_values( + expected_content + ) + assert_log_parent(log, parent_span) + + +def remove_none_values(body): + result = {} + for key, value in body.items(): + if value is None: + continue + if isinstance(value, dict): + result[key] = remove_none_values(value) + elif isinstance(value, list): + result[key] = [remove_none_values(i) for i in value] + else: + result[key] = value + return result + + +def assert_completion_attributes( + span: ReadableSpan, + request_model: str, + response: ChatCompletion, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + return assert_all_attributes( + span, + request_model, + response.id, + response.model, + response.usage.prompt_tokens, + response.usage.completion_tokens, + operation_name, + server_address, + ) + + +def assert_all_attributes( + span: ReadableSpan, + request_model: str, + response_id: str = None, + response_model: str = None, + input_tokens: Optional[int] = None, + output_tokens: Optional[int] = None, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + assert span.name == f"{operation_name} {request_model}" + assert ( + operation_name + == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + ) + assert ( + GenAIAttributes.GenAiSystemValues.OPENAI.value + == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] + ) + assert ( + request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + ) + if response_model: + assert ( + response_model + == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL not in span.attributes + + if response_id: + assert ( + response_id == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_ID not in span.attributes + + if input_tokens: + assert ( + input_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + ) + else: + assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS not in span.attributes + + if output_tokens: + assert ( + output_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + ) + else: + assert ( + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS not in span.attributes + ) + + assert server_address == span.attributes[ServerAttributes.SERVER_ADDRESS] + + +def assert_log_parent(log, span): + assert log.log_record.trace_id == span.get_span_context().trace_id + assert log.log_record.span_id == span.get_span_context().span_id + assert log.log_record.trace_flags == span.get_span_context().trace_flags + + +def get_current_weather_tool_definition(): + return { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA", + }, + }, + "required": ["location"], + "additionalProperties": False, + }, + }, + } From c32cc7a3e2031401b45adc0ffc2b92a0dd7219aa Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 14 Nov 2024 09:52:32 -0800 Subject: [PATCH 234/335] Remove updating CHANGELOG step in release workflow (#3000) --- .github/workflows/release.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d7b18edc8..97e51c9c63 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -118,36 +118,3 @@ jobs: # the step below is creating a pull request against main ref: main - - name: Copy change log updates to main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "VERSION=${STABLE_VERSION}\/${UNSTABLE_VERSION}" >> $GITHUB_ENV - echo "RELEASE_TAG=$STABLE_VERSION" >> $GITHUB_ENV - ./scripts/merge_changelog_to_main.sh - - - name: Use CLA approved github bot - run: .github/scripts/use-cla-approved-github-bot.sh - - - name: Create pull request against main - env: - # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows - GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} - run: | - message="Copy change log updates from $GITHUB_REF_NAME" - body="Copy log updates from \`$GITHUB_REF_NAME\`." - branch="opentelemetrybot/copy-change-log-updates-from-${GITHUB_REF_NAME//\//-}" - - if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then - if git diff --quiet; then - echo there are no updates needed to the change log on main, not creating pull request - exit 0 # success - fi - fi - - git commit -a -m "$message" - git push origin HEAD:$branch - gh pr create --title "$message" \ - --body "$body" \ - --head $branch \ - --base main From 803bb322ba77bc2afb30fb9c31fb8cdde04fc8d6 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 14 Nov 2024 19:08:03 +0100 Subject: [PATCH 235/335] opentelemetry-instrumentation-httpx: make instrument_client a staticmethod again (#3003) * opentelemetry-instrumentation-httpx: make instrument_client a staticmethod again * ADd changelog * Can be a classmethod --------- Co-authored-by: Leighton Chen --- CHANGELOG.md | 3 +++ .../opentelemetry/instrumentation/httpx/__init__.py | 11 ++++++----- .../tests/test_httpx_integration.py | 9 ++++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24760db6c8..772384bdde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `opentelemetry-instrumentation-httpx`: instrument_client is a static method again + ([#3003](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3003)) + ### Breaking changes - `opentelemetry-instrumentation-sqlalchemy` teach instruments version diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index d3a2cecfe6..4a2026e6de 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -938,8 +938,9 @@ async def _handle_async_request_wrapper( # pylint: disable=too-many-locals return response + @classmethod def instrument_client( - self, + cls, client: typing.Union[httpx.Client, httpx.AsyncClient], tracer_provider: TracerProvider = None, request_hook: typing.Union[ @@ -996,7 +997,7 @@ def instrument_client( client._transport, "handle_request", partial( - self._handle_request_wrapper, + cls._handle_request_wrapper, tracer=tracer, sem_conv_opt_in_mode=sem_conv_opt_in_mode, request_hook=request_hook, @@ -1008,7 +1009,7 @@ def instrument_client( transport, "handle_request", partial( - self._handle_request_wrapper, + cls._handle_request_wrapper, tracer=tracer, sem_conv_opt_in_mode=sem_conv_opt_in_mode, request_hook=request_hook, @@ -1021,7 +1022,7 @@ def instrument_client( client._transport, "handle_async_request", partial( - self._handle_async_request_wrapper, + cls._handle_async_request_wrapper, tracer=tracer, sem_conv_opt_in_mode=sem_conv_opt_in_mode, async_request_hook=async_request_hook, @@ -1033,7 +1034,7 @@ def instrument_client( transport, "handle_async_request", partial( - self._handle_async_request_wrapper, + cls._handle_async_request_wrapper, tracer=tracer, sem_conv_opt_in_mode=sem_conv_opt_in_mode, async_request_hook=async_request_hook, diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 07699700c4..b934ae0861 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -910,13 +910,20 @@ def test_suppress_instrumentation_new_client(self): self.assert_span(num_spans=0) - def test_instrument_client(self): + def test_instrument_client_called_on_the_instance(self): client = self.create_client() HTTPXClientInstrumentor().instrument_client(client) result = self.perform_request(self.URL, client=client) self.assertEqual(result.text, "Hello!") self.assert_span(num_spans=1) + def test_instrument_client_called_on_the_class(self): + client = self.create_client() + HTTPXClientInstrumentor.instrument_client(client) + result = self.perform_request(self.URL, client=client) + self.assertEqual(result.text, "Hello!") + self.assert_span(num_spans=1) + def test_instrumentation_without_client(self): HTTPXClientInstrumentor().instrument() results = [ From 23f67eb77bd46121a49b6a37a085080fff525e8d Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Mon, 18 Nov 2024 12:29:35 -0500 Subject: [PATCH 236/335] Cherry pick eachdist.py changes to main from release/v1.28.x-0.49bx branch (#3018) * Fix prepare patch release workflow (#3013) * Fix eachdist.py patch release to respect "all" and "excluded" (#3016) --- .github/scripts/update-version-patch.sh | 11 ++++ .github/workflows/prepare-patch-release.yml | 6 +- scripts/eachdist.py | 67 +++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100755 .github/scripts/update-version-patch.sh diff --git a/.github/scripts/update-version-patch.sh b/.github/scripts/update-version-patch.sh new file mode 100755 index 0000000000..fec7cd8260 --- /dev/null +++ b/.github/scripts/update-version-patch.sh @@ -0,0 +1,11 @@ +#!/bin/bash -e + +sed -i "/\[stable\]/{n;s/version=.*/version=$1/}" eachdist.ini +sed -i "/\[prerelease\]/{n;s/version=.*/version=$2/}" eachdist.ini + +./scripts/eachdist.py update_patch_versions \ + --stable_version=$1 \ + --unstable_version=$2 \ + --stable_version_prev=$3 \ + --unstable_version_prev=$4 + diff --git a/.github/workflows/prepare-patch-release.yml b/.github/workflows/prepare-patch-release.yml index 7c854d436d..51e1dd8208 100644 --- a/.github/workflows/prepare-patch-release.yml +++ b/.github/workflows/prepare-patch-release.yml @@ -40,14 +40,18 @@ jobs: exit 1 fi + stable_version_prev="$stable_major_minor.$((stable_patch))" + unstable_version_prev="0.${unstable_minor}b$((unstable_patch))" stable_version="$stable_major_minor.$((stable_patch + 1))" unstable_version="0.${unstable_minor}b$((unstable_patch + 1))" echo "STABLE_VERSION=$stable_version" >> $GITHUB_ENV echo "UNSTABLE_VERSION=$unstable_version" >> $GITHUB_ENV + echo "STABLE_VERSION_PREV=$stable_version_prev" >> $GITHUB_ENV + echo "UNSTABLE_VERSION_PREV=$unstable_version_prev" >> $GITHUB_ENV - name: Update version - run: .github/scripts/update-version.sh $STABLE_VERSION $UNSTABLE_VERSION + run: .github/scripts/update-version-patch.sh $STABLE_VERSION $UNSTABLE_VERSION $STABLE_VERSION_PREV $UNSTABLE_VERSION_PREV - name: Set up Python 3.9 uses: actions/setup-python@v5 diff --git a/scripts/eachdist.py b/scripts/eachdist.py index b82d16a8ec..ca490546eb 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -237,6 +237,16 @@ def setup_instparser(instparser): "releaseargs", nargs=argparse.REMAINDER, help=extraargs_help("pytest") ) + patchreleaseparser = subparsers.add_parser( + "update_patch_versions", + help="Updates version numbers during patch release, used by maintainers and CI", + ) + patchreleaseparser.set_defaults(func=patch_release_args) + patchreleaseparser.add_argument("--stable_version", required=True) + patchreleaseparser.add_argument("--unstable_version", required=True) + patchreleaseparser.add_argument("--stable_version_prev", required=True) + patchreleaseparser.add_argument("--unstable_version_prev", required=True) + fmtparser = subparsers.add_parser( "format", help="Formats all source code with black and isort.", @@ -655,6 +665,27 @@ def update_dependencies(targets, version, packages): ) +def update_patch_dependencies(targets, version, prev_version, packages): + print("updating patch dependencies") + if "all" in packages: + packages.extend(targets) + + # PEP 508 allowed specifier operators + operators = ["==", "!=", "<=", ">=", "<", ">", "===", "~=", "="] + operators_pattern = "|".join(re.escape(op) for op in operators) + + for pkg in packages: + search = rf"({basename(pkg)}[^,]*?)(\s?({operators_pattern})\s?)(.*{prev_version})" + replace = r"\g<1>\g<2>" + version + print(f"{search=}\t{replace=}\t{pkg=}") + update_files( + targets, + "pyproject.toml", + search, + replace, + ) + + def update_files(targets, filename, search, replace): errors = False for target in targets: @@ -687,10 +718,12 @@ def release_args(args): versions = args.versions updated_versions = [] + # remove excluded packages excluded = cfg["exclude_release"]["packages"].split() targets = [ target for target in targets if basename(target) not in excluded ] + for group in versions.split(","): mcfg = cfg[group] version = mcfg["version"] @@ -707,6 +740,40 @@ def release_args(args): update_changelogs("-".join(updated_versions)) +def patch_release_args(args): + print("preparing patch release") + + rootpath = find_projectroot() + targets = list(find_targets_unordered(rootpath)) + cfg = ConfigParser() + cfg.read(str(find_projectroot() / "eachdist.ini")) + + # remove excluded packages + excluded = cfg["exclude_release"]["packages"].split() + targets = [ + target for target in targets if basename(target) not in excluded + ] + + # stable + mcfg = cfg["stable"] + packages = mcfg["packages"].split() + print(f"update stable packages to {args.stable_version}") + + update_patch_dependencies( + targets, args.stable_version, args.stable_version_prev, packages + ) + update_version_files(targets, args.stable_version, packages) + + # prerelease + mcfg = cfg["prerelease"] + packages = mcfg["packages"].split() + print(f"update prerelease packages to {args.unstable_version}") + update_patch_dependencies( + targets, args.unstable_version, args.unstable_version_prev, packages + ) + update_version_files(targets, args.unstable_version, packages) + + def test_args(args): clean_remainder_args(args.pytestargs) execute_args( From a29ad8a6a3cd606d9ece02d86e8f5bca26e950b7 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 19 Nov 2024 09:26:10 +0100 Subject: [PATCH 237/335] Fix link to confluent_kafka docs (#3024) --- .../opentelemetry-instrumentation-confluent-kafka/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/README.rst b/instrumentation/opentelemetry-instrumentation-confluent-kafka/README.rst index 163c2a4393..1ce6dcbd26 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/README.rst +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/README.rst @@ -19,5 +19,5 @@ Installation References ---------- -* `OpenTelemetry confluent-kafka/ Tracing `_ +* `OpenTelemetry confluent-kafka/ Tracing `_ * `OpenTelemetry Project `_ From 53b87145b36d02db9fb45e0fa17bba4fc4e1713f Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:13:31 -0800 Subject: [PATCH 238/335] DB-API instrumentor populates span after sqlcomment creation, not before (#2935) --- CHANGELOG.md | 2 + .../instrumentation/dbapi/__init__.py | 91 ++++++++++--------- .../tests/test_dbapi_integration.py | 39 ++++++++ 3 files changed, 89 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 772384bdde..47db260d19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2635)) - `opentelemetry-instrumentation` Add support for string based dotted module paths in unwrap ([#2919](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2919)) +- `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute + ([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index fc3911f744..fb6416f52e 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -492,49 +492,54 @@ def traced_execution( with self._db_api_integration._tracer.start_as_current_span( name, kind=SpanKind.CLIENT ) as span: - self._populate_span(span, cursor, *args) - if args and self._commenter_enabled: - try: - args_list = list(args) - - # lazy capture of mysql-connector client version using cursor - if ( - self._db_api_integration.database_system == "mysql" - and self._db_api_integration.connect_module.__name__ - == "mysql.connector" - and not self._db_api_integration.commenter_data[ - "mysql_client_version" - ] - ): - self._db_api_integration.commenter_data[ - "mysql_client_version" - ] = cursor._cnx._cmysql.get_client_info() - - commenter_data = dict( - self._db_api_integration.commenter_data - ) - if self._commenter_options.get( - "opentelemetry_values", True - ): - commenter_data.update(**_get_opentelemetry_values()) - - # Filter down to just the requested attributes. - commenter_data = { - k: v - for k, v in commenter_data.items() - if self._commenter_options.get(k, True) - } - statement = _add_sql_comment( - args_list[0], **commenter_data - ) - - args_list[0] = statement - args = tuple(args_list) - - except Exception as exc: # pylint: disable=broad-except - _logger.exception( - "Exception while generating sql comment: %s", exc - ) + if span.is_recording(): + if args and self._commenter_enabled: + try: + args_list = list(args) + + # lazy capture of mysql-connector client version using cursor + if ( + self._db_api_integration.database_system == "mysql" + and self._db_api_integration.connect_module.__name__ + == "mysql.connector" + and not self._db_api_integration.commenter_data[ + "mysql_client_version" + ] + ): + self._db_api_integration.commenter_data[ + "mysql_client_version" + ] = cursor._cnx._cmysql.get_client_info() + + commenter_data = dict( + self._db_api_integration.commenter_data + ) + if self._commenter_options.get( + "opentelemetry_values", True + ): + commenter_data.update( + **_get_opentelemetry_values() + ) + + # Filter down to just the requested attributes. + commenter_data = { + k: v + for k, v in commenter_data.items() + if self._commenter_options.get(k, True) + } + statement = _add_sql_comment( + args_list[0], **commenter_data + ) + + args_list[0] = statement + args = tuple(args_list) + + except Exception as exc: # pylint: disable=broad-except + _logger.exception( + "Exception while generating sql comment: %s", exc + ) + + self._populate_span(span, cursor, *args) + return query_method(*args, **kwargs) diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index e29a8ad380..ae595fb430 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -14,6 +14,7 @@ import logging +import re from unittest import mock from opentelemetry import context @@ -306,6 +307,44 @@ def __getattr__(self, name): r"Select 1 /\*dbapi_level='1.0',dbapi_threadsafety='unknown',driver_paramstyle='unknown',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + def test_executemany_comment_matches_db_statement_attribute(self): + connect_module = mock.MagicMock() + connect_module.__version__ = mock.MagicMock() + connect_module.__libpq_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": False, "dbapi_level": False}, + connect_module=connect_module, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/", + ) + + cursor_span_id = re.search(r"[a-zA-Z0-9_]{16}", cursor.query).group() + db_statement_span_id = re.search( + r"[a-zA-Z0-9_]{16}", span.attributes[SpanAttributes.DB_STATEMENT] + ).group() + self.assertEqual(cursor_span_id, db_statement_span_id) + def test_compatible_build_version_psycopg_psycopg2_libpq(self): connect_module = mock.MagicMock() connect_module.__name__ = "test" From 1c820ea96e72b246c0d8afc4edb2775046acb6f6 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:30:26 -0800 Subject: [PATCH 239/335] SQLAlchemy instrumentor populates span after sqlcomment creation, not before (#2937) --- CHANGELOG.md | 6 ++- .../instrumentation/sqlalchemy/engine.py | 39 ++++++++++--------- .../tests/test_sqlcommenter.py | 34 ++++++++++++++++ 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47db260d19..bd686f6089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976)) - Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap` ([#2996](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2996)) + - `opentelemetry-instrumentation-sqlalchemy` Add sqlcomment to `db.statement` attribute + ([#2937](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2937)) + - `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute + ([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935)) ### Fixed @@ -44,8 +48,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2635)) - `opentelemetry-instrumentation` Add support for string based dotted module paths in unwrap ([#2919](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2919)) -- `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute - ([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py index 172c1193f3..b64af796d1 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py @@ -219,28 +219,31 @@ def _before_cur_exec( ) with trace.use_span(span, end_on_exit=False): if span.is_recording(): + if self.enable_commenter: + commenter_data = { + "db_driver": conn.engine.driver, + # Driver/framework centric information. + "db_framework": f"sqlalchemy:{sqlalchemy.__version__}", + } + + if self.commenter_options.get( + "opentelemetry_values", True + ): + commenter_data.update(**_get_opentelemetry_values()) + + # Filter down to just the requested attributes. + commenter_data = { + k: v + for k, v in commenter_data.items() + if self.commenter_options.get(k, True) + } + + statement = _add_sql_comment(statement, **commenter_data) + span.set_attribute(SpanAttributes.DB_STATEMENT, statement) span.set_attribute(SpanAttributes.DB_SYSTEM, self.vendor) for key, value in attrs.items(): span.set_attribute(key, value) - if self.enable_commenter: - commenter_data = { - "db_driver": conn.engine.driver, - # Driver/framework centric information. - "db_framework": f"sqlalchemy:{sqlalchemy.__version__}", - } - - if self.commenter_options.get("opentelemetry_values", True): - commenter_data.update(**_get_opentelemetry_values()) - - # Filter down to just the requested attributes. - commenter_data = { - k: v - for k, v in commenter_data.items() - if self.commenter_options.get(k, True) - } - - statement = _add_sql_comment(statement, **commenter_data) context._otel_span = span diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py index ec2fc51e5b..8490721e3e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging +import re import pytest from sqlalchemy import ( @@ -21,6 +22,7 @@ from opentelemetry import context from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor +from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase @@ -59,6 +61,38 @@ def test_sqlcommenter_enabled(self): r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + def test_sqlcommenter_enabled_matches_db_statement_attribute(self): + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={"db_framework": False}, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + query_log = self.caplog.records[-2].getMessage() + self.assertRegex( + query_log, + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + cnx_span_id = re.search(r"[a-zA-Z0-9_]{16}", query_log).group() + db_statement_span_id = re.search( + r"[a-zA-Z0-9_]{16}", + query_span.attributes[SpanAttributes.DB_STATEMENT], + ).group() + self.assertEqual(cnx_span_id, db_statement_span_id) + def test_sqlcommenter_enabled_otel_values_false(self): engine = create_engine("sqlite:///:memory:") SQLAlchemyInstrumentor().instrument( From 19a59e4be73301140903826a445e27614435112c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:40:06 -0300 Subject: [PATCH 240/335] fix(httpx): check if mount transport is None before wrap (#3022) --- CHANGELOG.md | 2 + .../instrumentation/httpx/__init__.py | 46 ++++++++-------- .../tests/test_httpx_integration.py | 54 +++++++++++++++++-- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd686f6089..92e366402a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx`: instrument_client is a static method again ([#3003](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3003)) +- `opentelemetry-instrumentation-httpx`: Check if mount transport is none before wrap it + ([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 4a2026e6de..92e044bf06 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -1005,17 +1005,18 @@ def instrument_client( ), ) for transport in client._mounts.values(): - wrap_function_wrapper( - transport, - "handle_request", - partial( - cls._handle_request_wrapper, - tracer=tracer, - sem_conv_opt_in_mode=sem_conv_opt_in_mode, - request_hook=request_hook, - response_hook=response_hook, - ), - ) + if hasattr(transport, "handle_request"): + wrap_function_wrapper( + transport, + "handle_request", + partial( + cls._handle_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + request_hook=request_hook, + response_hook=response_hook, + ), + ) client._is_instrumented_by_opentelemetry = True if hasattr(client._transport, "handle_async_request"): wrap_function_wrapper( @@ -1030,17 +1031,18 @@ def instrument_client( ), ) for transport in client._mounts.values(): - wrap_function_wrapper( - transport, - "handle_async_request", - partial( - cls._handle_async_request_wrapper, - tracer=tracer, - sem_conv_opt_in_mode=sem_conv_opt_in_mode, - async_request_hook=async_request_hook, - async_response_hook=async_response_hook, - ), - ) + if hasattr(transport, "handle_async_request"): + wrap_function_wrapper( + transport, + "handle_async_request", + partial( + cls._handle_async_request_wrapper, + tracer=tracer, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + async_request_hook=async_request_hook, + async_response_hook=async_response_hook, + ), + ) client._is_instrumented_by_opentelemetry = True @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index b934ae0861..0fdab381d5 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -741,6 +741,10 @@ def create_client( def create_proxy_transport(self, url: str): pass + @abc.abstractmethod + def get_transport_handler(self, transport): + pass + def setUp(self): super().setUp() self.client = self.create_client() @@ -763,17 +767,15 @@ def assert_proxy_mounts(self, mounts, num_mounts, transport_type=None): self.assertEqual(len(mounts), num_mounts) for transport in mounts: with self.subTest(transport): + if transport is None: + continue if transport_type: self.assertIsInstance( transport, transport_type, ) else: - handler = getattr(transport, "handle_request", None) - if not handler: - handler = getattr( - transport, "handle_async_request" - ) + handler = self.get_transport_handler(transport) self.assertTrue( isinstance(handler, ObjectProxy) and getattr(handler, "__wrapped__") @@ -983,6 +985,21 @@ def test_uninstrument_new_client(self): self.assertEqual(result.text, "Hello!") self.assert_span() + @mock.patch.dict( + "os.environ", {"NO_PROXY": "http://mock/status/200"}, clear=True + ) + def test_instrument_with_no_proxy(self): + proxy_mounts = self.create_proxy_mounts() + HTTPXClientInstrumentor().instrument() + client = self.create_client(mounts=proxy_mounts) + result = self.perform_request(self.URL, client=client) + self.assert_span(num_spans=1) + self.assertEqual(result.text, "Hello!") + self.assert_proxy_mounts( + client._mounts.values(), + 3, + ) + def test_instrument_proxy(self): proxy_mounts = self.create_proxy_mounts() HTTPXClientInstrumentor().instrument() @@ -994,6 +1011,27 @@ def test_instrument_proxy(self): 2, ) + @mock.patch.dict( + "os.environ", {"NO_PROXY": "http://mock/status/200"}, clear=True + ) + def test_instrument_client_with_no_proxy(self): + proxy_mounts = self.create_proxy_mounts() + client = self.create_client(mounts=proxy_mounts) + self.assert_proxy_mounts( + client._mounts.values(), + 3, + (httpx.HTTPTransport, httpx.AsyncHTTPTransport), + ) + HTTPXClientInstrumentor.instrument_client(client) + result = self.perform_request(self.URL, client=client) + self.assertEqual(result.text, "Hello!") + self.assert_span(num_spans=1) + self.assert_proxy_mounts( + client._mounts.values(), + 3, + ) + HTTPXClientInstrumentor.uninstrument_client(client) + def test_instrument_client_with_proxy(self): proxy_mounts = self.create_proxy_mounts() client = self.create_client(mounts=proxy_mounts) @@ -1188,6 +1226,9 @@ def perform_request( def create_proxy_transport(self, url): return httpx.HTTPTransport(proxy=httpx.Proxy(url)) + def get_transport_handler(self, transport): + return getattr(transport, "handle_request", None) + def test_can_instrument_subclassed_client(self): class CustomClient(httpx.Client): pass @@ -1241,6 +1282,9 @@ async def _perform_request(): def create_proxy_transport(self, url): return httpx.AsyncHTTPTransport(proxy=httpx.Proxy(url)) + def get_transport_handler(self, transport): + return getattr(transport, "handle_async_request", None) + def test_basic_multiple(self): # We need to create separate clients because in httpx >= 0.19, # closing the client after "with" means the second http call fails From ae13079df8ca150480aa870c965c7828a80e7e22 Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:48:27 +0800 Subject: [PATCH 241/335] Add OpenAI example (#3006) --- .pylintrc | 2 +- CHANGELOG.md | 2 +- .../CHANGELOG.md | 2 + .../README.rst | 8 +++- .../example/.env | 18 +++++++++ .../example/README.rst | 39 +++++++++++++++++++ .../example/main.py | 21 ++++++++++ .../example/requirements.txt | 6 +++ 8 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/main.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt diff --git a/.pylintrc b/.pylintrc index 39ea7b5d35..bc3b25c978 100644 --- a/.pylintrc +++ b/.pylintrc @@ -7,7 +7,7 @@ extension-pkg-whitelist=cassandra # Add list of files or directories to be excluded. They should be base names, not # paths. -ignore=CVS,gen,Dockerfile,docker-compose.yml,README.md,requirements.txt,docs +ignore=CVS,gen,Dockerfile,docker-compose.yml,README.md,requirements.txt,docs,.venv # Add files or directories matching the regex patterns to be excluded. The # regex matches against base names, not paths. diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e366402a..19a819cbe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-sqlalchemy` Update unit tests to run with SQLALchemy 2 ([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976)) - - Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap` +- Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap` ([#2996](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2996)) - `opentelemetry-instrumentation-sqlalchemy` Add sqlcomment to `db.statement` attribute ([#2937](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2937)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 07b10615c1..2c10498511 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Add example to `opentelemetry-instrumentation-openai-v2` + ([#3006](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3006)) - Support for `AsyncOpenAI/AsyncCompletions` ([#2984](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2984)) ## Version 2.0b0 (2024-11-08) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst index 85817896ff..bbd142a97e 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst @@ -6,17 +6,21 @@ OpenTelemetry OpenAI Instrumentation .. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-openai-v2.svg :target: https://pypi.org/project/opentelemetry-instrumentation-openai-v2/ -Instrumentation with OpenAI that supports the OpenAI library and is -specified to trace_integration using 'OpenAI'. +This library allows tracing LLM requests and logging of messages made by the +`OpenAI Python API library `_. Installation ------------ +If your application is already instrumented with OpenTelemetry, add this +package to your requirements. :: pip install opentelemetry-instrumentation-openai-v2 +If you don't have an OpenAI application, yet, try our `example `_ +which only needs a valid OpenAI API key. References ---------- diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env new file mode 100644 index 0000000000..d6afa66723 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env @@ -0,0 +1,18 @@ +# Update this with your real OpenAI API key +OPENAI_API_KEY=sk-YOUR_API_KEY + +# Uncomment to use Ollama instead of OpenAI +# OPENAI_BASE_URL=http://localhost:11434/v1 +# OPENAI_API_KEY=unused +# CHAT_MODEL=qwen2.5:0.5b + +OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 +OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +OTEL_SERVICE_NAME=opentelemetry-python-openai + +# Change to 'false' to disable logging +OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true +# Change to 'console' if your OTLP endpoint doesn't support logs +OTEL_LOGS_EXPORTER=otlp_proto_http +# Change to 'false' to hide prompt and completion content +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst new file mode 100644 index 0000000000..019e141c70 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst @@ -0,0 +1,39 @@ +OpenTelemetry OpenAI Instrumentation Example +============================================ + +This is an example of how to instrument OpenAI calls with zero code changes, +using `opentelemetry-instrument`. + +When `main.py `_ is run, it exports traces and logs to an OTLP +compatible endpoint. Traces include details such as the model used and the +duration of the chat request. Logs capture the chat request and the generated +response, providing a comprehensive view of the performance and behavior of +your OpenAI requests. + +Setup +----- + +Minimally, update the `.env <.env>`_ file with your "OPENAI_API_KEY". An +OTLP compatible endpoint should be listening for traces and logs on +http://localhost:4318. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example like this: + +:: + + dotenv run -- opentelemetry-instrument python main.py + +You should see a poem generated by OpenAI while traces and logs export to your +configured observability tool. diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/main.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/main.py new file mode 100644 index 0000000000..d41b1dd933 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/main.py @@ -0,0 +1,21 @@ +import os + +from openai import OpenAI + + +def main(): + client = OpenAI() + chat_completion = client.chat.completions.create( + model=os.getenv("CHAT_MODEL", "gpt-4o-mini"), + messages=[ + { + "role": "user", + "content": "Write a short poem on OpenTelemetry.", + }, + ], + ) + print(chat_completion.choices[0].message.content) + + +if __name__ == "__main__": + main() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt new file mode 100644 index 0000000000..9ec9bff320 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt @@ -0,0 +1,6 @@ +openai~=1.54.4 + +opentelemetry-sdk~=1.28.2 +opentelemetry-exporter-otlp-proto-http~=1.28.2 +opentelemetry-distro~=0.49b2 +opentelemetry-instrumentation-openai-v2~=2.0b0 From 0032e68161471b94c764a6e62ee4d1d2def23db1 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 20 Nov 2024 01:01:12 -0800 Subject: [PATCH 242/335] Update RELEASING.md (#3001) --- RELEASING.md | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 2706d36c8f..490269e2e4 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -9,8 +9,9 @@ (otherwise the workflow will pick up the version from `main` and just remove the `.dev` suffix). * Review the two pull requests that it creates. (one is targeted to the release branch and one is targeted to `main`). - * Merge the one targeted towards the release branch. - * The builds will fail for the `main` pr because of validation rules. Follow the [release workflow](https://github.com/open-telemetry/opentelemetry-python/blob/main/RELEASING.md) for the core repo up until this same point. Change the SHAs of each PR to point at each other to get the `main` builds to pass. + * The builds will fail for both the `main` and release pr because of validation rules. Follow the [release workflow](https://github.com/open-telemetry/opentelemetry-python/blob/main/RELEASING.md) for the core repo up until this same point. Change the SHAs of each PR to point at each other to get the `main` and release builds to pass. + * Merge the release PR. + * Merge the PR to main (this can be done separately from [making the release](#making-the-release)) ### Preparing a major or minor release for individual package @@ -62,6 +63,7 @@ The workflow can only be run against long-term release branch such as `package-r * Review and merge the pull request that it creates for updating the change log in main (note that if this is not a patch release then the change log on main may already be up-to-date, in which case no pull request will be created). + * Verify that a new [Github release](https://github.com/open-telemetry/opentelemetry-python-contrib/releases) has been created and that the CHANGELOGs look correct. ### Releasing individual package @@ -79,6 +81,14 @@ to pick a specific package to release. The workflow can only be run against long-term release branch such as `package-release/{package-name}/v{major}.{minor}.x` or `package-release/{package-name}/v{major}.{minor}bx`. +## After the release + +* Check PyPI + * This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/release.yml). + * Check the [action logs](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml) to make sure packages have been uploaded to PyPI + * Check the release history (e.g. https://pypi.org/project/opentelemetry-instrumentation/#history) on PyPI + * If for some reason the action failed, see [Publish failed](#publish-failed) below + ## Notes about version numbering for stable components * The version number for stable components in the `main` branch is always `X.Y.0.dev`, @@ -110,28 +120,6 @@ The workflow can only be run against long-term release branch such as `package-r * The version number for unstable components in the `main` branch will be bumped to the next version, e.g. `0.{Y+1}b0.dev`. -## After the release - -* Check PyPI - * This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/release.yml). - * Check the [action logs](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml) to make sure packages have been uploaded to PyPI - * Check the release history (e.g. https://pypi.org/project/opentelemetry-instrumentation/#history) on PyPI - * If for some reason the action failed, see [Publish failed](#publish-failed) below -* Move stable tag - * Run the following (TODO automate): - - ```bash - git tag -d stable - git tag stable - git push --delete origin tagname - git push origin stable - ``` - - * This will ensure the docs are pointing at the stable release. - * To validate this worked, ensure the stable build has run successfully: - . - If the build has not run automatically, it can be manually trigger via the readthedocs interface. - ## Releasing dev version of new packages to claim namespace When a contribution introduces a new package, in order to mitigate name-squatting incidents, release the current development version of the new package under the `opentelemetry` user to simply claim the namespace. This should be done shortly after the PR that introduced this package has been merged into `main`. From d0cbf8e1a58de7c3d7b4ccaebc6d6607004d3b7d Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:54:06 +0800 Subject: [PATCH 243/335] Correct formatting of CHANGELOG (#3029) Signed-off-by: Adrian Cole Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a819cbe2..62ac86a211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,9 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976)) - Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap` ([#2996](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2996)) - - `opentelemetry-instrumentation-sqlalchemy` Add sqlcomment to `db.statement` attribute +- `opentelemetry-instrumentation-sqlalchemy` Add sqlcomment to `db.statement` attribute ([#2937](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2937)) - - `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute +- `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute ([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935)) ### Fixed From 4e992dd60a384184ed6f0ad91ae59b896efc38d6 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:44:56 -0800 Subject: [PATCH 244/335] DB-API instrument_connection accepts optional connect_module (#3027) * DbApi instrument_connection accepts optional connect_module * Changelog * Add test * Adjust tests --- CHANGELOG.md | 2 + .../instrumentation/dbapi/__init__.py | 3 ++ .../tests/test_dbapi_integration.py | 37 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62ac86a211..25002bb657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2937](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2937)) - `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute ([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935)) +- `opentelemetry-instrumentation-dbapi` instrument_connection accepts optional connect_module + ([#3027](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3027)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index fb6416f52e..d8db967f47 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -190,6 +190,7 @@ def instrument_connection( capture_parameters: bool = False, enable_commenter: bool = False, commenter_options: dict = None, + connect_module: typing.Callable[..., typing.Any] = None, ): """Enable instrumentation in a database connection. @@ -204,6 +205,7 @@ def instrument_connection( capture_parameters: Configure if db.statement.parameters should be captured. enable_commenter: Flag to enable/disable sqlcommenter. commenter_options: Configurations for tags to be appended at the sql query. + connect_module: Module name where connect method is available. Returns: An instrumented connection. @@ -221,6 +223,7 @@ def instrument_connection( capture_parameters=capture_parameters, enable_commenter=enable_commenter, commenter_options=commenter_options, + connect_module=connect_module, ) db_integration.get_connection_attributes(connection) return get_traced_connection_proxy(connection, db_integration) diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index ae595fb430..2ffa2f3d5b 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -592,6 +592,43 @@ def test_instrument_connection(self): connection2 = dbapi.instrument_connection(self.tracer, connection, "-") self.assertIs(connection2.__wrapped__, connection) + @mock.patch("opentelemetry.instrumentation.dbapi.DatabaseApiIntegration") + def test_instrument_connection_kwargs_defaults(self, mock_dbapiint): + dbapi.instrument_connection(self.tracer, mock.Mock(), "foo") + kwargs = mock_dbapiint.call_args[1] + self.assertEqual(kwargs["connection_attributes"], None) + self.assertEqual(kwargs["version"], "") + self.assertEqual(kwargs["tracer_provider"], None) + self.assertEqual(kwargs["capture_parameters"], False) + self.assertEqual(kwargs["enable_commenter"], False) + self.assertEqual(kwargs["commenter_options"], None) + self.assertEqual(kwargs["connect_module"], None) + + @mock.patch("opentelemetry.instrumentation.dbapi.DatabaseApiIntegration") + def test_instrument_connection_kwargs_provided(self, mock_dbapiint): + mock_tracer_provider = mock.MagicMock() + mock_connect_module = mock.MagicMock() + dbapi.instrument_connection( + self.tracer, + mock.Mock(), + "foo", + connection_attributes={"foo": "bar"}, + version="test", + tracer_provider=mock_tracer_provider, + capture_parameters=True, + enable_commenter=True, + commenter_options={"foo": "bar"}, + connect_module=mock_connect_module, + ) + kwargs = mock_dbapiint.call_args[1] + self.assertEqual(kwargs["connection_attributes"], {"foo": "bar"}) + self.assertEqual(kwargs["version"], "test") + self.assertIs(kwargs["tracer_provider"], mock_tracer_provider) + self.assertEqual(kwargs["capture_parameters"], True) + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": "bar"}) + self.assertIs(kwargs["connect_module"], mock_connect_module) + def test_uninstrument_connection(self): connection = mock.Mock() # Set connection.database to avoid a failure because mock can't From beff723389288b6cfc890d8780cdc426f4f11720 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Thu, 21 Nov 2024 07:37:08 -0800 Subject: [PATCH 245/335] Add mysqlclient instrumentor support for sqlcommenting (#2941) * WIP * Add _DB_DRIVER_ALIASES * Add mysql_client_version to sqlcomment * lint * Fix existing tests * lint test * Add PyMySQL dbapi commenter case * Add test * Add test * Add test * Add tests * Changelog * calculate_commenter_data at init of DatabaseApiIntegration * Add mysqlclient sqlcomment support * Fix typo * try-except if NoneType module * Add unit test * CHangelog * mysqlclient instrument_connection with connect_module * add tests * more tests * more tests 2 * lint * Redesign tests * Rm unnecessary mocks --- CHANGELOG.md | 2 + .../instrumentation/mysqlclient/__init__.py | 86 +++++- .../tests/test_mysqlclient_integration.py | 251 ++++++++++++++++++ 3 files changed, 335 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25002bb657..c3ec7e3798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935)) - `opentelemetry-instrumentation-dbapi` instrument_connection accepts optional connect_module ([#3027](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3027)) +- `opentelemetry-instrumentation-mysqlclient` Add sqlcommenter support + ([#2941](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2941)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py index 85083cff2e..5b08b0b50d 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py @@ -36,6 +36,72 @@ cursor.close() cnx.close() +SQLCOMMENTER +***************************************** +You can optionally configure MySQLClient instrumentation to enable sqlcommenter which enriches +the query with contextual information. + +.. code:: python + + import MySQLdb + from opentelemetry.instrumentation.mysqlclient import MySQLClientInstrumentor + + + MySQLClientInstrumentor().instrument(enable_commenter=True, commenter_options={}) + + cnx = MySQLdb.connect(database="MySQL_Database") + cursor = cnx.cursor() + cursor.execute("INSERT INTO test (testField) VALUES (123)" + cnx.commit() + cursor.close() + cnx.close() + +For example, +:: + + Invoking cursor.execute("INSERT INTO test (testField) VALUES (123)") will lead to sql query "INSERT INTO test (testField) VALUES (123)" but when SQLCommenter is enabled + the query will get appended with some configurable tags like "INSERT INTO test (testField) VALUES (123) /*tag=value*/;" + +SQLCommenter Configurations +*************************** +We can configure the tags to be appended to the sqlquery log by adding configuration inside commenter_options(default:{}) keyword + +db_driver = True(Default) or False + +For example, +:: +Enabling this flag will add MySQLdb and its version, e.g. /*MySQLdb%%3A1.2.3*/ + +dbapi_threadsafety = True(Default) or False + +For example, +:: +Enabling this flag will add threadsafety /*dbapi_threadsafety=2*/ + +dbapi_level = True(Default) or False + +For example, +:: +Enabling this flag will add dbapi_level /*dbapi_level='2.0'*/ + +mysql_client_version = True(Default) or False + +For example, +:: +Enabling this flag will add mysql_client_version /*mysql_client_version='123'*/ + +driver_paramstyle = True(Default) or False + +For example, +:: +Enabling this flag will add driver_paramstyle /*driver_paramstyle='pyformat'*/ + +opentelemetry_values = True(Default) or False + +For example, +:: +Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ + API --- """ @@ -59,14 +125,16 @@ class MySQLClientInstrumentor(BaseInstrumentor): - def instrumentation_dependencies(self) -> Collection[str]: + def instrumentation_dependencies(self) -> Collection[str]: # pylint: disable=no-self-use return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs): # pylint: disable=no-self-use """Integrate with the mysqlclient library. https://github.com/PyMySQL/mysqlclient/ """ tracer_provider = kwargs.get("tracer_provider") + enable_sqlcommenter = kwargs.get("enable_commenter", False) + commenter_options = kwargs.get("commenter_options", {}) dbapi.wrap_connect( __name__, @@ -76,14 +144,21 @@ def _instrument(self, **kwargs): _CONNECTION_ATTRIBUTES, version=__version__, tracer_provider=tracer_provider, + enable_commenter=enable_sqlcommenter, + commenter_options=commenter_options, ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs): # pylint: disable=no-self-use """ "Disable mysqlclient instrumentation""" dbapi.unwrap_connect(MySQLdb, "connect") @staticmethod - def instrument_connection(connection, tracer_provider=None): + def instrument_connection( + connection, + tracer_provider=None, + enable_commenter=None, + commenter_options=None, + ): """Enable instrumentation in a mysqlclient connection. Args: @@ -102,6 +177,9 @@ def instrument_connection(connection, tracer_provider=None): _CONNECTION_ATTRIBUTES, version=__version__, tracer_provider=tracer_provider, + enable_commenter=enable_commenter, + commenter_options=commenter_options, + connect_module=MySQLdb, ) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py index 35fdecc8e1..5c375ac4aa 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py @@ -23,6 +23,7 @@ class TestMySQLClientIntegration(TestBase): + # pylint: disable=invalid-name def tearDown(self): super().tearDown() with self.disable_logging(): @@ -96,6 +97,256 @@ def test_instrument_connection(self, mock_connect): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 1) + @mock.patch("opentelemetry.instrumentation.dbapi.instrument_connection") + @mock.patch("MySQLdb.connect") + # pylint: disable=unused-argument + def test_instrument_connection_enable_commenter_dbapi_kwargs( + self, + mock_connect, + mock_instrument_connection, + ): + cnx = MySQLdb.connect(database="test") + cnx = MySQLClientInstrumentor().instrument_connection( + cnx, + enable_commenter=True, + commenter_options={"foo": True}, + ) + cursor = cnx.cursor() + cursor.execute("Select 1;") + kwargs = mock_instrument_connection.call_args[1] + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": True}) + + def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + cnx_proxy = MySQLClientInstrumentor().instrument_connection( + mock_connection, + enable_commenter=True, + ) + cnx_proxy.cursor().execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + cnx_proxy = MySQLClientInstrumentor().instrument_connection( + mock_connection, + enable_commenter=True, + commenter_options={ + "dbapi_level": False, + "dbapi_threadsafety": True, + "driver_paramstyle": False, + }, + ) + cnx_proxy.cursor().execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + cnx_proxy = MySQLClientInstrumentor().instrument_connection( + mock_connection, + ) + cnx_proxy.cursor().execute("Select 1;") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + "Select 1;", + ) + + @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") + @mock.patch("MySQLdb.connect") + # pylint: disable=unused-argument + def test_instrument_enable_commenter_dbapi_kwargs( + self, + mock_connect, + mock_wrap_connect, + ): + MySQLClientInstrumentor()._instrument( + enable_commenter=True, + commenter_options={"foo": True}, + ) + kwargs = mock_wrap_connect.call_args[1] + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": True}) + + def test_instrument_with_dbapi_sqlcomment_enabled( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + MySQLClientInstrumentor()._instrument( + enable_commenter=True, + ) + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_with_dbapi_sqlcomment_enabled_with_options( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + MySQLClientInstrumentor()._instrument( + enable_commenter=True, + commenter_options={ + "dbapi_level": False, + "dbapi_threadsafety": True, + "driver_paramstyle": False, + }, + ) + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_with_dbapi_sqlcomment_not_enabled_default( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + MySQLClientInstrumentor()._instrument() + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + "Select 1;", + ) + @mock.patch("MySQLdb.connect") # pylint: disable=unused-argument def test_uninstrument_connection(self, mock_connect): From 7b1554bddc45505633e9e86621f114477d08a19b Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:21:12 -0800 Subject: [PATCH 246/335] Add PyMySQL instrumentor support for sqlcommenting (#2942) * WIP * Add _DB_DRIVER_ALIASES * Add mysql_client_version to sqlcomment * lint * Fix existing tests * lint test * Add PyMySQL dbapi commenter case * Add test * Add test * Add test * Add tests * Changelog * calculate_commenter_data at init of DatabaseApiIntegration * try-except if NoneType module * Add pymysql sqlcomment support * Add unit tests * Update docstring * Changelog * pymysql instrument_connection specifies connect_module * lint * Add tests * Fix doc --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../instrumentation/pymysql/__init__.py | 91 ++++++- .../tests/test_pymysql_integration.py | 239 ++++++++++++++++++ 3 files changed, 327 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3ec7e3798..1298977849 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2635)) - `opentelemetry-instrumentation` Add support for string based dotted module paths in unwrap ([#2919](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2919)) +- `opentelemetry-instrumentation-pymysql` Add sqlcommenter support + ([#2942](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2942)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py index c48a5b6b3d..eb4435813d 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py @@ -26,7 +26,6 @@ import pymysql from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor - PyMySQLInstrumentor().instrument() cnx = pymysql.connect(database="MySQL_Database") @@ -36,6 +35,76 @@ cursor.close() cnx.close() +SQLCOMMENTER +***************************************** +You can optionally configure PyMySQL instrumentation to enable sqlcommenter which enriches +the query with contextual information. + +Usage +----- + +.. code:: python + + import pymysql + from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor + + PyMySQLInstrumentor().instrument(enable_commenter=True, commenter_options={}) + + cnx = pymysql.connect(database="MySQL_Database") + cursor = cnx.cursor() + cursor.execute("INSERT INTO test (testField) VALUES (123)" + cnx.commit() + cursor.close() + cnx.close() + + +For example, +:: + + Invoking cursor.execute("INSERT INTO test (testField) VALUES (123)") will lead to sql query "INSERT INTO test (testField) VALUES (123)" but when SQLCommenter is enabled + the query will get appended with some configurable tags like "INSERT INTO test (testField) VALUES (123) /*tag=value*/;" + + +SQLCommenter Configurations +*************************** +We can configure the tags to be appended to the sqlquery log by adding configuration inside commenter_options(default:{}) keyword + +db_driver = True(Default) or False + +For example, +:: +Enabling this flag will add pymysql and its version, e.g. /*pymysql%%3A1.2.3*/ + +dbapi_threadsafety = True(Default) or False + +For example, +:: +Enabling this flag will add threadsafety /*dbapi_threadsafety=2*/ + +dbapi_level = True(Default) or False + +For example, +:: +Enabling this flag will add dbapi_level /*dbapi_level='2.0'*/ + +mysql_client_version = True(Default) or False + +For example, +:: +Enabling this flag will add mysql_client_version /*mysql_client_version='123'*/ + +driver_paramstyle = True(Default) or False + +For example, +:: +Enabling this flag will add driver_paramstyle /*driver_paramstyle='pyformat'*/ + +opentelemetry_values = True(Default) or False + +For example, +:: +Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ + API --- """ @@ -59,14 +128,16 @@ class PyMySQLInstrumentor(BaseInstrumentor): - def instrumentation_dependencies(self) -> Collection[str]: + def instrumentation_dependencies(self) -> Collection[str]: # pylint: disable=no-self-use return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs): # pylint: disable=no-self-use """Integrate with the PyMySQL library. https://github.com/PyMySQL/PyMySQL/ """ tracer_provider = kwargs.get("tracer_provider") + enable_sqlcommenter = kwargs.get("enable_commenter", False) + commenter_options = kwargs.get("commenter_options", {}) dbapi.wrap_connect( __name__, @@ -76,14 +147,21 @@ def _instrument(self, **kwargs): _CONNECTION_ATTRIBUTES, version=__version__, tracer_provider=tracer_provider, + enable_commenter=enable_sqlcommenter, + commenter_options=commenter_options, ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs): # pylint: disable=no-self-use """ "Disable PyMySQL instrumentation""" dbapi.unwrap_connect(pymysql, "connect") @staticmethod - def instrument_connection(connection, tracer_provider=None): + def instrument_connection( + connection, + tracer_provider=None, + enable_commenter=None, + commenter_options=None, + ): """Enable instrumentation in a PyMySQL connection. Args: @@ -102,6 +180,9 @@ def instrument_connection(connection, tracer_provider=None): _CONNECTION_ATTRIBUTES, version=__version__, tracer_provider=tracer_provider, + enable_commenter=enable_commenter, + commenter_options=commenter_options, + connect_module=pymysql, ) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py index 6f8af5d8df..3ba5ee2356 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py @@ -24,6 +24,7 @@ class TestPyMysqlIntegration(TestBase): + # pylint: disable=invalid-name def tearDown(self): super().tearDown() with self.disable_logging(): @@ -111,6 +112,244 @@ def test_instrument_connection(self, mock_connect): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 1) + @mock.patch("opentelemetry.instrumentation.dbapi.instrument_connection") + @mock.patch("pymysql.connect") + # pylint: disable=unused-argument + def test_instrument_connection_enable_commenter_dbapi_kwargs( + self, + mock_connect, + mock_instrument_connection, + ): + cnx = pymysql.connect(database="test") + cnx = PyMySQLInstrumentor().instrument_connection( + cnx, + enable_commenter=True, + commenter_options={"foo": True}, + ) + cursor = cnx.cursor() + cursor.execute("SELECT * FROM test") + kwargs = mock_instrument_connection.call_args[1] + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": True}) + + def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + cnx_proxy = PyMySQLInstrumentor().instrument_connection( + mock_connection, + enable_commenter=True, + ) + cnx_proxy.cursor().execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + cnx_proxy = PyMySQLInstrumentor().instrument_connection( + mock_connection, + enable_commenter=True, + commenter_options={ + "dbapi_level": False, + "dbapi_threadsafety": True, + "driver_paramstyle": False, + }, + ) + cnx_proxy.cursor().execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + cnx_proxy = PyMySQLInstrumentor().instrument_connection( + mock_connection, + ) + cnx_proxy.cursor().execute("Select 1;") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + "Select 1;", + ) + + @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") + @mock.patch("pymysql.connect") + # pylint: disable=unused-argument + def test_instrument_enable_commenter_dbapi_kwargs( + self, + mock_connect, + mock_wrap_connect, + ): + PyMySQLInstrumentor()._instrument( + enable_commenter=True, + commenter_options={"foo": True}, + ) + kwargs = mock_wrap_connect.call_args[1] + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": True}) + + def test_instrument_with_dbapi_sqlcomment_enabled( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + PyMySQLInstrumentor()._instrument( + enable_commenter=True, + ) + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_with_dbapi_sqlcomment_enabled_with_options( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + PyMySQLInstrumentor()._instrument( + enable_commenter=True, + commenter_options={ + "dbapi_level": False, + "dbapi_threadsafety": True, + "driver_paramstyle": False, + }, + ) + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + + def test_instrument_with_dbapi_sqlcomment_not_enabled_default( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + PyMySQLInstrumentor()._instrument() + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + "Select 1;", + ) + @mock.patch("pymysql.connect") # pylint: disable=unused-argument def test_uninstrument_connection(self, mock_connect): From 116f98df72aac6c620217d5060089a737e21b4cd Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 21 Nov 2024 17:52:22 +0100 Subject: [PATCH 247/335] opentelemetry-instrumentation-httpx: drop unused private classes (#3036) --- CHANGELOG.md | 2 + .../instrumentation/httpx/__init__.py | 71 ------------------- 2 files changed, 2 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1298977849..51ecc94d8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2971](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2971)) - Drop `opentelemetry-instrumentation-test` package from default instrumentation list ([#2969](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2969)) +- `opentelemetry-instrumentation-httpx`: remove private unused `_InstrumentedClient` and `_InstrumentedAsyncClient` classes + ([#3036](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3036)) ## Version 1.28.0/0.49b0 (2024-11-05) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 92e044bf06..195c784408 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -641,77 +641,6 @@ async def aclose(self) -> None: await self._transport.aclose() -class _InstrumentedClient(httpx.Client): - _tracer_provider = None - _request_hook = None - _response_hook = None - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self._original_transport = self._transport - self._original_mounts = self._mounts.copy() - self._is_instrumented_by_opentelemetry = True - - self._transport = SyncOpenTelemetryTransport( - self._transport, - tracer_provider=_InstrumentedClient._tracer_provider, - request_hook=_InstrumentedClient._request_hook, - response_hook=_InstrumentedClient._response_hook, - ) - self._mounts.update( - { - url_pattern: ( - SyncOpenTelemetryTransport( - transport, - tracer_provider=_InstrumentedClient._tracer_provider, - request_hook=_InstrumentedClient._request_hook, - response_hook=_InstrumentedClient._response_hook, - ) - if transport is not None - else transport - ) - for url_pattern, transport in self._original_mounts.items() - } - ) - - -class _InstrumentedAsyncClient(httpx.AsyncClient): - _tracer_provider = None - _request_hook = None - _response_hook = None - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self._original_transport = self._transport - self._original_mounts = self._mounts.copy() - self._is_instrumented_by_opentelemetry = True - - self._transport = AsyncOpenTelemetryTransport( - self._transport, - tracer_provider=_InstrumentedAsyncClient._tracer_provider, - request_hook=_InstrumentedAsyncClient._request_hook, - response_hook=_InstrumentedAsyncClient._response_hook, - ) - - self._mounts.update( - { - url_pattern: ( - AsyncOpenTelemetryTransport( - transport, - tracer_provider=_InstrumentedAsyncClient._tracer_provider, - request_hook=_InstrumentedAsyncClient._request_hook, - response_hook=_InstrumentedAsyncClient._response_hook, - ) - if transport is not None - else transport - ) - for url_pattern, transport in self._original_mounts.items() - } - ) - - class HTTPXClientInstrumentor(BaseInstrumentor): # pylint: disable=protected-access,attribute-defined-outside-init """An instrumentor for httpx Client and AsyncClient From d9e14487b2bc2bdcc638d635091bfe2019ecbc2d Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 21 Nov 2024 23:12:51 +0100 Subject: [PATCH 248/335] opentelemetry-instrumentation-system-metrics: fix typo in metrics configs (#3025) --- CHANGELOG.md | 2 ++ .../instrumentation/system_metrics/__init__.py | 5 +++-- .../tests/test_system_metrics.py | 12 ++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ecc94d8c..b5339972d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx`: instrument_client is a static method again ([#3003](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3003)) +- `opentelemetry-instrumentation-system_metrics`: fix callbacks reading wrong config + ([#3025](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3025)) - `opentelemetry-instrumentation-httpx`: Check if mount transport is none before wrap it ([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022)) diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index 4e1ee2a5df..aff86ea77b 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -40,6 +40,7 @@ "process.runtime.thread_count": None, "process.runtime.cpu.utilization": None, "process.runtime.context_switches": ["involuntary", "voluntary"], + "process.open_file_descriptor.count": None, } Usage @@ -595,7 +596,7 @@ def _get_system_network_packets( """Observer callback for network packets""" for device, counters in psutil.net_io_counters(pernic=True).items(): - for metric in self._config["system.network.dropped.packets"]: + for metric in self._config["system.network.packets"]: recv_sent = {"receive": "recv", "transmit": "sent"}[metric] if hasattr(counters, f"packets_{recv_sent}"): self._system_network_packets_labels["device"] = device @@ -626,7 +627,7 @@ def _get_system_network_io( """Observer callback for network IO""" for device, counters in psutil.net_io_counters(pernic=True).items(): - for metric in self._config["system.network.dropped.packets"]: + for metric in self._config["system.network.io"]: recv_sent = {"receive": "recv", "transmit": "sent"}[metric] if hasattr(counters, f"bytes_{recv_sent}"): self._system_network_io_labels["device"] = device diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py index 83abcff4c0..92c30a66f0 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/tests/test_system_metrics.py @@ -20,6 +20,7 @@ from unittest import mock, skipIf from opentelemetry.instrumentation.system_metrics import ( + _DEFAULT_CONFIG, SystemMetricsInstrumentor, ) from opentelemetry.sdk.metrics import MeterProvider @@ -865,3 +866,14 @@ def test_open_file_descriptor_count(self, mock_process_num_fds): expected, ) mock_process_num_fds.assert_called() + + +class TestConfigSystemMetrics(TestBase): + # pylint:disable=no-self-use + def test_that_correct_config_is_read(self): + for key, value in _DEFAULT_CONFIG.items(): + meter_provider = MeterProvider([InMemoryMetricReader()]) + instrumentor = SystemMetricsInstrumentor(config={key: value}) + instrumentor.instrument(meter_provider=meter_provider) + meter_provider.force_flush() + instrumentor.uninstrument() From 5c5fc732fb0792f3aad3582cabdf2f290c95c541 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Fri, 22 Nov 2024 00:32:04 -0800 Subject: [PATCH 249/335] Replace assertEqualSpanInstrumentationInfo with assertEqualSpanInstrumentationScope (#3037) * Replace assertInstInfo with assertInstScope * Update Changelog * Fix order of other changelog entries --- CHANGELOG.md | 6 ++++-- .../tests/test_aiopg_integration.py | 8 ++++---- .../tests/test_cassandra_integration.py | 2 +- .../tests/test_elasticsearch.py | 4 ++-- .../tests/test_aio_client_interceptor.py | 8 ++++---- .../tests/test_aio_server_interceptor.py | 14 +++++++------- .../tests/test_client_interceptor.py | 10 +++++----- .../tests/test_client_interceptor_filter.py | 18 +++++++++--------- .../tests/test_server_interceptor.py | 14 +++++++------- .../tests/test_server_interceptor_filter.py | 4 ++-- .../tests/test_httpx_integration.py | 10 +++++----- .../tests/test_mysql_integration.py | 2 +- .../tests/test_mysqlclient_integration.py | 2 +- .../tests/test_psycopg_integration.py | 8 ++++---- .../tests/test_psycopg2_integration.py | 2 +- .../tests/test_pymysql_integration.py | 2 +- .../tests/test_requests_integration.py | 2 +- .../tests/test_urllib_integration.py | 8 ++++---- 18 files changed, 63 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5339972d7..173abf88f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3027](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3027)) - `opentelemetry-instrumentation-mysqlclient` Add sqlcommenter support ([#2941](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2941)) +- `opentelemetry-instrumentation-pymysql` Add sqlcommenter support + ([#2942](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2942)) ### Fixed @@ -34,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3025](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3025)) - `opentelemetry-instrumentation-httpx`: Check if mount transport is none before wrap it ([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022)) +- Replace all instrumentor unit test `assertEqualSpanInstrumentationInfo` calls with `assertEqualSpanInstrumentationScope` calls + ([#3037](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3037)) ### Breaking changes @@ -58,8 +62,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2635)) - `opentelemetry-instrumentation` Add support for string based dotted module paths in unwrap ([#2919](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2919)) -- `opentelemetry-instrumentation-pymysql` Add sqlcommenter support - ([#2942](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2942)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py b/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py index c497ae4564..f32ef3514b 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py @@ -67,7 +67,7 @@ def test_instrumentor_connect(self): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.aiopg ) @@ -96,7 +96,7 @@ async def _ctx_manager_connect(): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.aiopg ) @@ -117,7 +117,7 @@ def test_instrumentor_create_pool(self): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.aiopg ) @@ -148,7 +148,7 @@ async def _ctx_manager_pool(): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.aiopg ) diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py b/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py index ed488ab07f..9a36bb9069 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py @@ -78,7 +78,7 @@ def test_instrumentor( span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.cassandra ) self.assertEqual(span.name, "Cassandra") diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py index b7e24d87c9..8a707c8c2a 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py @@ -114,7 +114,7 @@ def test_instrumentor(self, request_mock): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.elasticsearch ) @@ -608,7 +608,7 @@ def test_bulk(self, request_mock): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.elasticsearch ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py index 7ae1649149..4cd19da4af 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py @@ -114,7 +114,7 @@ async def test_unary_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -142,7 +142,7 @@ async def test_unary_stream(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -170,7 +170,7 @@ async def test_stream_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -200,7 +200,7 @@ async def test_stream_stream(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py index 050f6f8d13..ee917ca26c 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_server_interceptor.py @@ -105,7 +105,7 @@ async def request(channel): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -164,7 +164,7 @@ async def request(channel): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -217,7 +217,7 @@ async def request(channel): self.assertIs(parent_span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( parent_span, opentelemetry.instrumentation.grpc ) @@ -263,7 +263,7 @@ async def request(channel): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -318,7 +318,7 @@ async def request(channel): self.assertIs(parent_span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( parent_span, opentelemetry.instrumentation.grpc ) @@ -514,7 +514,7 @@ async def request(channel): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -579,7 +579,7 @@ async def request(channel): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py index 38759352b3..9fb922a615 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py @@ -111,7 +111,7 @@ def test_unary_unary_future(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -125,7 +125,7 @@ def test_unary_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -151,7 +151,7 @@ def test_unary_stream(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -177,7 +177,7 @@ def test_stream_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -205,7 +205,7 @@ def test_stream_stream(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_filter.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_filter.py index b6ae975dff..81e8d708f2 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_filter.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor_filter.py @@ -116,7 +116,7 @@ def test_unary_unary_future(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -130,7 +130,7 @@ def test_unary_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -260,7 +260,7 @@ def test_unary_unary_future(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -274,7 +274,7 @@ def test_unary_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -443,7 +443,7 @@ def test_unary_unary_future(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -457,7 +457,7 @@ def test_unary_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -483,7 +483,7 @@ def test_unary_stream(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -509,7 +509,7 @@ def test_stream_unary(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -537,7 +537,7 @@ def test_stream_stream(self): self.assertIs(span.kind, trace.SpanKind.CLIENT) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor.py index de79269894..08aa16187a 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor.py @@ -120,7 +120,7 @@ def handler(request, context): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -188,7 +188,7 @@ def test_create_span(self): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -252,7 +252,7 @@ def SimpleMethod(self, request, context): self.assertIs(parent_span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( parent_span, opentelemetry.instrumentation.grpc ) @@ -307,7 +307,7 @@ def test_create_span_streaming(self): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -371,7 +371,7 @@ def ServerStreamingMethod(self, request, context): self.assertIs(parent_span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( parent_span, opentelemetry.instrumentation.grpc ) @@ -594,7 +594,7 @@ def unset_status_handler(request, context): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -626,7 +626,7 @@ def unset_status_handler(request, context): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor_filter.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor_filter.py index 95e70236cb..6a0081c4af 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor_filter.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_server_interceptor_filter.py @@ -109,7 +109,7 @@ def handler(request, context): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) @@ -195,7 +195,7 @@ def test_create_span(self): self.assertIs(span.kind, trace.SpanKind.SERVER) # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.grpc ) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 0fdab381d5..148fe27893 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -216,7 +216,7 @@ def test_basic(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.httpx ) @@ -240,7 +240,7 @@ def test_nonstandard_http_method(self): self.assertIs(span.status.status_code, trace.StatusCode.ERROR) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.httpx ) @@ -269,7 +269,7 @@ def test_nonstandard_http_method_new_semconv(self): self.assertIs(span.status.status_code, trace.StatusCode.ERROR) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.httpx ) @@ -309,7 +309,7 @@ def test_basic_new_semconv(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.httpx ) @@ -350,7 +350,7 @@ def test_basic_both_semconv(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.httpx ) diff --git a/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py b/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py index 3614febffd..79399cce7f 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py @@ -50,7 +50,7 @@ def test_instrumentor(self, mock_connect): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.mysql ) diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py index 5c375ac4aa..ae221f68f4 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py @@ -44,7 +44,7 @@ def test_instrumentor(self, mock_connect): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.mysqlclient ) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py index dc9969ba8c..4ddaad9174 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py @@ -182,7 +182,7 @@ def test_instrumentor(self): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.psycopg ) @@ -213,7 +213,7 @@ def test_instrumentor_with_connection_class(self): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.psycopg ) @@ -407,7 +407,7 @@ async def test_async_connection(): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.psycopg ) @@ -435,7 +435,7 @@ async def test_async_connection(): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.psycopg ) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py index 6671073043..9a6a5ff2fa 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py @@ -100,7 +100,7 @@ def test_instrumentor(self): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.psycopg2 ) diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py index 3ba5ee2356..82294236f0 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py @@ -45,7 +45,7 @@ def test_instrumentor(self, mock_connect): span = spans_list[0] # Check version and name in span's instrumentation info - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.pymysql ) diff --git a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py index a5cb8927ae..366cd0c233 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py +++ b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py @@ -166,7 +166,7 @@ def test_basic(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.requests ) diff --git a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py index 8ac0284939..b085cc50d5 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py @@ -158,7 +158,7 @@ def test_basic(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.urllib ) @@ -182,7 +182,7 @@ def test_basic_new_semconv(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.urllib ) @@ -209,7 +209,7 @@ def test_basic_both_semconv(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.urllib ) @@ -344,7 +344,7 @@ def test_response_code_none(self): self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqualSpanInstrumentationInfo( + self.assertEqualSpanInstrumentationScope( span, opentelemetry.instrumentation.urllib ) From 1737ee694080d9645776e23fbb96ac290a8f0e16 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 26 Nov 2024 00:43:11 -0800 Subject: [PATCH 250/335] Use OTLP log exporter by default in otel-distro (#3042) * Use OTLP log exporter by default in otel-distro * changelog * sort imports --- CHANGELOG.md | 2 ++ opentelemetry-distro/src/opentelemetry/distro/__init__.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 173abf88f4..b194cd8b9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-distro` default to OTLP log exporter. + ([#3042](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3042)) - `opentelemetry-instrumentation-sqlalchemy` Update unit tests to run with SQLALchemy 2 ([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976)) - Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap` diff --git a/opentelemetry-distro/src/opentelemetry/distro/__init__.py b/opentelemetry-distro/src/opentelemetry/distro/__init__.py index ad61f01ca7..474c2db239 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/__init__.py +++ b/opentelemetry-distro/src/opentelemetry/distro/__init__.py @@ -15,6 +15,7 @@ import os from opentelemetry.environment_variables import ( + OTEL_LOGS_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_TRACES_EXPORTER, ) @@ -37,4 +38,5 @@ class OpenTelemetryDistro(BaseDistro): def _configure(self, **kwargs): os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp") os.environ.setdefault(OTEL_METRICS_EXPORTER, "otlp") + os.environ.setdefault(OTEL_LOGS_EXPORTER, "otlp") os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, "grpc") From 41bd34f6e176737aac41a607c905090ca17dc965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:16:45 -0300 Subject: [PATCH 251/335] infra: configure generate-workflows to generate core-contrib-tests (#3035) * test call workflow Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix name Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/workflows/core_contrib_test_0.yml | 1910 +++++++++++++++++ .github/workflows/generate_workflows.py | 2 + .../src/generate_workflows_lib/__init__.py | 8 +- ...ontrib.yml.j2 => core_contrib_test.yml.j2} | 19 +- 4 files changed, 1923 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/core_contrib_test_0.yml rename .github/workflows/generate_workflows_lib/src/generate_workflows_lib/{contrib.yml.j2 => core_contrib_test.yml.j2} (69%) diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml new file mode 100644 index 0000000000..a5aea916df --- /dev/null +++ b/.github/workflows/core_contrib_test_0.yml @@ -0,0 +1,1910 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Core Contrib Test 0 + +on: + workflow_call: + inputs: + CORE_REPO_SHA: + required: true + type: string + +env: + CORE_REPO_SHA: ${{ inputs.CORE_REPO_SHA }} + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + py38-test-instrumentation-openai-v2-0: + name: instrumentation-openai-v2-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-openai-v2-0 -- -ra + + py38-test-instrumentation-openai-v2-1: + name: instrumentation-openai-v2-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-openai-v2-1 -- -ra + + py38-test-resource-detector-container: + name: resource-detector-container + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-resource-detector-container -- -ra + + py38-test-resource-detector-azure-0: + name: resource-detector-azure-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-resource-detector-azure-0 -- -ra + + py38-test-resource-detector-azure-1: + name: resource-detector-azure-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-resource-detector-azure-1 -- -ra + + py38-test-sdk-extension-aws-0: + name: sdk-extension-aws-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-sdk-extension-aws-0 -- -ra + + py38-test-sdk-extension-aws-1: + name: sdk-extension-aws-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-sdk-extension-aws-1 -- -ra + + py38-test-distro: + name: distro + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-distro -- -ra + + py38-test-opentelemetry-instrumentation: + name: opentelemetry-instrumentation + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-opentelemetry-instrumentation -- -ra + + py38-test-instrumentation-aiohttp-client: + name: instrumentation-aiohttp-client + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiohttp-client -- -ra + + py38-test-instrumentation-aiohttp-server: + name: instrumentation-aiohttp-server + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiohttp-server -- -ra + + py38-test-instrumentation-aiopg: + name: instrumentation-aiopg + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiopg -- -ra + + py38-test-instrumentation-aws-lambda: + name: instrumentation-aws-lambda + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aws-lambda -- -ra + + py38-test-instrumentation-botocore: + name: instrumentation-botocore + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-botocore -- -ra + + py38-test-instrumentation-boto3sqs: + name: instrumentation-boto3sqs + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-boto3sqs -- -ra + + py38-test-instrumentation-django-0: + name: instrumentation-django-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-django-0 -- -ra + + py38-test-instrumentation-django-1: + name: instrumentation-django-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-django-1 -- -ra + + py38-test-instrumentation-django-2: + name: instrumentation-django-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-django-2 -- -ra + + py38-test-instrumentation-dbapi: + name: instrumentation-dbapi + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-dbapi -- -ra + + py38-test-instrumentation-boto: + name: instrumentation-boto + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-boto -- -ra + + py38-test-instrumentation-elasticsearch-0: + name: instrumentation-elasticsearch-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra + + py38-test-instrumentation-elasticsearch-1: + name: instrumentation-elasticsearch-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra + + py38-test-instrumentation-elasticsearch-2: + name: instrumentation-elasticsearch-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra + + py38-test-instrumentation-falcon-0: + name: instrumentation-falcon-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-0 -- -ra + + py38-test-instrumentation-falcon-1: + name: instrumentation-falcon-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-1 -- -ra + + py38-test-instrumentation-falcon-2: + name: instrumentation-falcon-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-2 -- -ra + + py38-test-instrumentation-fastapi: + name: instrumentation-fastapi + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-fastapi -- -ra + + py38-test-instrumentation-flask-0: + name: instrumentation-flask-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-0 -- -ra + + py38-test-instrumentation-flask-1: + name: instrumentation-flask-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-1 -- -ra + + py38-test-instrumentation-flask-2: + name: instrumentation-flask-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-2 -- -ra + + py38-test-instrumentation-urllib: + name: instrumentation-urllib + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-urllib -- -ra + + py38-test-instrumentation-urllib3-0: + name: instrumentation-urllib3-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-urllib3-0 -- -ra + + py38-test-instrumentation-urllib3-1: + name: instrumentation-urllib3-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-urllib3-1 -- -ra + + py38-test-instrumentation-requests: + name: instrumentation-requests + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-requests -- -ra + + py38-test-instrumentation-starlette: + name: instrumentation-starlette + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-starlette -- -ra + + py38-test-instrumentation-jinja2: + name: instrumentation-jinja2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-jinja2 -- -ra + + py38-test-instrumentation-logging: + name: instrumentation-logging + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-logging -- -ra + + py38-test-exporter-richconsole: + name: exporter-richconsole + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-exporter-richconsole -- -ra + + py38-test-exporter-prometheus-remote-write: + name: exporter-prometheus-remote-write + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-exporter-prometheus-remote-write -- -ra + + py38-test-instrumentation-mysql-0: + name: instrumentation-mysql-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysql-0 -- -ra + + py38-test-instrumentation-mysql-1: + name: instrumentation-mysql-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysql-1 -- -ra + + py38-test-instrumentation-mysqlclient: + name: instrumentation-mysqlclient + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysqlclient -- -ra + + py38-test-instrumentation-psycopg2: + name: instrumentation-psycopg2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg2 -- -ra + + py38-test-instrumentation-psycopg: + name: instrumentation-psycopg + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg -- -ra + + py38-test-instrumentation-pymemcache-0: + name: instrumentation-pymemcache-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra + + py38-test-instrumentation-pymemcache-1: + name: instrumentation-pymemcache-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra + + py38-test-instrumentation-pymemcache-2: + name: instrumentation-pymemcache-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra + + py38-test-instrumentation-pymemcache-3: + name: instrumentation-pymemcache-3 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra + + py38-test-instrumentation-pymemcache-4: + name: instrumentation-pymemcache-4 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra + + py38-test-instrumentation-pymongo: + name: instrumentation-pymongo + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymongo -- -ra + + py38-test-instrumentation-pymysql: + name: instrumentation-pymysql + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pymysql -- -ra + + py38-test-instrumentation-pyramid: + name: instrumentation-pyramid + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-pyramid -- -ra + + py38-test-instrumentation-asgi: + name: instrumentation-asgi + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asgi -- -ra + + py38-test-instrumentation-asyncpg: + name: instrumentation-asyncpg + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asyncpg -- -ra + + py38-test-instrumentation-sqlite3: + name: instrumentation-sqlite3 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sqlite3 -- -ra + + py38-test-instrumentation-wsgi: + name: instrumentation-wsgi + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-wsgi -- -ra + + py38-test-instrumentation-grpc-0: + name: instrumentation-grpc-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-grpc-0 -- -ra + + py38-test-instrumentation-grpc-1: + name: instrumentation-grpc-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-grpc-1 -- -ra + + py38-test-instrumentation-sqlalchemy-1: + name: instrumentation-sqlalchemy-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra + + py38-test-instrumentation-sqlalchemy-2: + name: instrumentation-sqlalchemy-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sqlalchemy-2 -- -ra + + py38-test-instrumentation-redis: + name: instrumentation-redis + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-redis -- -ra + + py38-test-instrumentation-remoulade: + name: instrumentation-remoulade + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-remoulade -- -ra + + py38-test-instrumentation-celery: + name: instrumentation-celery + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-celery -- -ra + + py38-test-instrumentation-system-metrics: + name: instrumentation-system-metrics + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-system-metrics -- -ra + + py38-test-instrumentation-threading: + name: instrumentation-threading + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-threading -- -ra + + py38-test-instrumentation-tornado: + name: instrumentation-tornado + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-tornado -- -ra + + py38-test-instrumentation-tortoiseorm: + name: instrumentation-tortoiseorm + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-tortoiseorm -- -ra + + py38-test-instrumentation-httpx-0: + name: instrumentation-httpx-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-httpx-0 -- -ra + + py38-test-instrumentation-httpx-1: + name: instrumentation-httpx-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-httpx-1 -- -ra + + py38-test-util-http: + name: util-http + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-util-http -- -ra + + py38-test-propagator-aws-xray-0: + name: propagator-aws-xray-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-aws-xray-0 -- -ra + + py38-test-propagator-aws-xray-1: + name: propagator-aws-xray-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-aws-xray-1 -- -ra + + py38-test-propagator-ot-trace: + name: propagator-ot-trace + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-ot-trace -- -ra + + py38-test-instrumentation-sio-pika-0: + name: instrumentation-sio-pika-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sio-pika-0 -- -ra + + py38-test-instrumentation-sio-pika-1: + name: instrumentation-sio-pika-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sio-pika-1 -- -ra + + py38-test-instrumentation-aio-pika-0: + name: instrumentation-aio-pika-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-0 -- -ra + + py38-test-instrumentation-aio-pika-1: + name: instrumentation-aio-pika-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-1 -- -ra + + py38-test-instrumentation-aio-pika-2: + name: instrumentation-aio-pika-2 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-2 -- -ra + + py38-test-instrumentation-aio-pika-3: + name: instrumentation-aio-pika-3 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-3 -- -ra + + py38-test-instrumentation-aiokafka: + name: instrumentation-aiokafka + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiokafka -- -ra + + py38-test-instrumentation-kafka-python: + name: instrumentation-kafka-python + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-kafka-python -- -ra + + py38-test-instrumentation-kafka-pythonng: + name: instrumentation-kafka-pythonng + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-kafka-pythonng -- -ra + + py38-test-instrumentation-confluent-kafka: + name: instrumentation-confluent-kafka + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-confluent-kafka -- -ra + + py38-test-instrumentation-asyncio: + name: instrumentation-asyncio + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asyncio -- -ra + + py38-test-instrumentation-cassandra: + name: instrumentation-cassandra + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-cassandra -- -ra + + py38-test-processor-baggage: + name: processor-baggage + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-processor-baggage -- -ra diff --git a/.github/workflows/generate_workflows.py b/.github/workflows/generate_workflows.py index bda8eee827..09391a240c 100644 --- a/.github/workflows/generate_workflows.py +++ b/.github/workflows/generate_workflows.py @@ -1,6 +1,7 @@ from pathlib import Path from generate_workflows_lib import ( + generate_contrib_workflow, generate_lint_workflow, generate_misc_workflow, generate_test_workflow, @@ -12,3 +13,4 @@ generate_test_workflow(tox_ini_path, workflows_directory_path, "ubuntu-latest") generate_lint_workflow(tox_ini_path, workflows_directory_path) generate_misc_workflow(tox_ini_path, workflows_directory_path) +generate_contrib_workflow(workflows_directory_path) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index 0308fbe5f3..e60e8e8f81 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -170,14 +170,14 @@ def get_misc_job_datas(tox_envs: list) -> list: def _generate_workflow( - job_datas: list, name: str, workflow_directory_path: Path + job_datas: list, name: str, workflow_directory_path: Path, max_jobs=250 ): # Github seems to limit the amount of jobs in a workflow file, that is why # they are split in groups of 250 per workflow file. for file_number, job_datas in enumerate( [ - job_datas[index : index + 250] - for index in range(0, len(job_datas), 250) + job_datas[index : index + max_jobs] + for index in range(0, len(job_datas), max_jobs) ] ): with open( @@ -219,7 +219,7 @@ def generate_contrib_workflow( get_contrib_job_datas( get_tox_envs(Path(__file__).parent.joinpath("tox.ini")) ), - "contrib", + "core_contrib_test", workflow_directory_path, ) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 similarity index 69% rename from .github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 rename to .github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 index 2989e55974..9b0d40f6fd 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/contrib.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 @@ -1,16 +1,17 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Contrib {{ file_number }} +name: Core Contrib Test {{ file_number }} on: - push: - branches-ignore: - - 'release/*' - pull_request: + workflow_call: + inputs: + CORE_REPO_SHA: + required: true + type: string env: - CORE_REPO_SHA: ${% raw %}{{ github.sha }}{% endraw %} + CORE_REPO_SHA: ${% raw %}{{ inputs.CORE_REPO_SHA }}{% endraw %} CONTRIB_REPO_SHA: main PIP_EXISTS_ACTION: w @@ -27,12 +28,6 @@ jobs: repository: open-telemetry/opentelemetry-python-contrib ref: ${% raw %}{{ env.CONTRIB_REPO_SHA }}{% endraw %} - - name: Checkout core repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} - uses: actions/checkout@v4 - with: - repository: open-telemetry/opentelemetry-python - path: opentelemetry-python-core - - name: Set up Python 3.8 uses: actions/setup-python@v5 with: From 97d1514b6533a67a8194d225e9f3a32ec1444aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:03:42 -0300 Subject: [PATCH 252/335] fix missing contrib_repo_sha in workflow (#3049) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/core_contrib_test_0.yml | 6 ++++-- .../src/generate_workflows_lib/core_contrib_test.yml.j2 | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index a5aea916df..b67b9eae42 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -9,10 +9,12 @@ on: CORE_REPO_SHA: required: true type: string - + CONTRIB_REPO_SHA: + required: true + type: string env: CORE_REPO_SHA: ${{ inputs.CORE_REPO_SHA }} - CONTRIB_REPO_SHA: main + CONTRIB_REPO_SHA: ${{ inputs.CONTRIB_REPO_SHA }} PIP_EXISTS_ACTION: w jobs: diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 index 9b0d40f6fd..5553caf8eb 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 @@ -9,10 +9,12 @@ on: CORE_REPO_SHA: required: true type: string - + CONTRIB_REPO_SHA: + required: true + type: string env: CORE_REPO_SHA: ${% raw %}{{ inputs.CORE_REPO_SHA }}{% endraw %} - CONTRIB_REPO_SHA: main + CONTRIB_REPO_SHA: ${% raw %}{{ inputs.CONTRIB_REPO_SHA }}{% endraw %} PIP_EXISTS_ACTION: w jobs: From 16ebf2519b6e5f5762d359e4da3ae8b445227690 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 26 Nov 2024 22:46:47 +0100 Subject: [PATCH 253/335] starlette: Replace `_meter_provider` by `meter_provider` on `_instrument` (#3048) * starlette: Replace `_meter_provider` by `meter_provider` on `_instrument` * Add PR on the changelog --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/starlette/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b194cd8b9a..e6cb0ebb53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `opentelemetry-instrumentation-starlette`: Retrieve `meter_provider` key instead of `_meter_provider` on `_instrument` + ([#3048](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3048)) - `opentelemetry-instrumentation-httpx`: instrument_client is a static method again ([#3003](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3003)) - `opentelemetry-instrumentation-system_metrics`: fix callbacks reading wrong config diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index 50d2fb03d8..820fa29411 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -265,7 +265,7 @@ def _instrument(self, **kwargs): _InstrumentedStarlette._client_response_hook = kwargs.get( "client_response_hook" ) - _InstrumentedStarlette._meter_provider = kwargs.get("_meter_provider") + _InstrumentedStarlette._meter_provider = kwargs.get("meter_provider") applications.Starlette = _InstrumentedStarlette From d330ab3dd055f7da69f273d2cf1074dd128dfd62 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 27 Nov 2024 09:38:38 +0100 Subject: [PATCH 254/335] Add click instrumentation (#2994) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add instrumentation for click based CLI apps Co-authored-by: Anuraag (Rag) Agrawal * Add tox * Add Changelog * Silence pylint * Update tox.ini Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Update instrumentation/opentelemetry-instrumentation-click/pyproject.toml * Add baseline version * Adhere to new cli span semconv * Update workflows --------- Co-authored-by: Anuraag (Rag) Agrawal Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/core_contrib_test_0.yml | 22 ++ .github/workflows/lint_0.yml | 18 ++ .github/workflows/test_0.yml | 216 +++++++++--------- .github/workflows/test_1.yml | 144 +++++++++--- .github/workflows/test_2.yml | 53 +++++ CHANGELOG.md | 2 + instrumentation/README.md | 1 + .../README.rst | 24 ++ .../pyproject.toml | 54 +++++ .../instrumentation/click/__init__.py | 122 ++++++++++ .../instrumentation/click/package.py | 16 ++ .../instrumentation/click/version.py | 15 ++ .../test-requirements.txt | 15 ++ .../tests/test_click.py | 176 ++++++++++++++ .../pyproject.toml | 1 + .../instrumentation/bootstrap_gen.py | 4 + tox.ini | 14 ++ 17 files changed, 753 insertions(+), 144 deletions(-) create mode 100644 .github/workflows/test_2.yml create mode 100644 instrumentation/opentelemetry-instrumentation-click/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-click/pyproject.toml create mode 100644 instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/package.py create mode 100644 instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py create mode 100644 instrumentation/opentelemetry-instrumentation-click/test-requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-click/tests/test_click.py diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index b67b9eae42..67bda629ff 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -459,6 +459,28 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-boto -- -ra + py38-test-instrumentation-click: + name: instrumentation-click + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-click -- -ra + py38-test-instrumentation-elasticsearch-0: name: instrumentation-elasticsearch-0 runs-on: ubuntu-latest diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index 1fd3198785..9d77ef5e27 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -286,6 +286,24 @@ jobs: - name: Run tests run: tox -e lint-instrumentation-boto + lint-instrumentation-click: + name: instrumentation-click + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-click + lint-instrumentation-elasticsearch: name: instrumentation-elasticsearch runs-on: ubuntu-latest diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index 1b8376fdc2..47c9a19cf3 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -2032,6 +2032,114 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-boto -- -ra + py38-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-click -- -ra + + py39-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-click -- -ra + + py310-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-click -- -ra + + py311-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-click -- -ra + + py312-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-click -- -ra + + pypy3-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-click -- -ra + py38-test-instrumentation-elasticsearch-0_ubuntu-latest: name: instrumentation-elasticsearch-0 3.8 Ubuntu runs-on: ubuntu-latest @@ -4407,111 +4515,3 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-psycopg2 -- -ra - - py38-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-psycopg -- -ra - - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra - - py310-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-psycopg -- -ra - - py311-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-psycopg -- -ra - - py312-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-psycopg -- -ra - - pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-psycopg -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 227c891d0b..9c5d48aea3 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,114 @@ env: jobs: + py38-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg -- -ra + + py39-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg -- -ra + + py310-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg -- -ra + + py311-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg -- -ra + + py312-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg -- -ra + + pypy3-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-psycopg -- -ra + py38-test-instrumentation-pymemcache-0_ubuntu-latest: name: instrumentation-pymemcache-0 3.8 Ubuntu runs-on: ubuntu-latest @@ -4407,39 +4515,3 @@ jobs: - name: Run tests run: tox -e py311-test-processor-baggage -- -ra - - py312-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-processor-baggage -- -ra - - pypy3-test-processor-baggage_ubuntu-latest: - name: processor-baggage pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-processor-baggage -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml new file mode 100644 index 0000000000..c23866ffa8 --- /dev/null +++ b/.github/workflows/test_2.yml @@ -0,0 +1,53 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Test 2 + +on: + push: + branches-ignore: + - 'release/*' + pull_request: + +env: + CORE_REPO_SHA: main + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + py312-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-processor-baggage -- -ra + + pypy3-test-processor-baggage_ubuntu-latest: + name: processor-baggage pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-processor-baggage -- -ra diff --git a/CHANGELOG.md b/CHANGELOG.md index e6cb0ebb53..a28c5039c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2941](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2941)) - `opentelemetry-instrumentation-pymysql` Add sqlcommenter support ([#2942](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2942)) +- `opentelemetry-instrumentation-click`: new instrumentation to trace click commands + ([#2994](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2994)) ### Fixed diff --git a/instrumentation/README.md b/instrumentation/README.md index fb601266ea..bff37fde6c 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -15,6 +15,7 @@ | [opentelemetry-instrumentation-botocore](./opentelemetry-instrumentation-botocore) | botocore ~= 1.0 | No | experimental | [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | experimental | [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | experimental +| [opentelemetry-instrumentation-click](./opentelemetry-instrumentation-click) | click >= 8.1.3, < 9.0.0 | No | experimental | [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.4.0 | No | experimental | [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | experimental | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental diff --git a/instrumentation/opentelemetry-instrumentation-click/README.rst b/instrumentation/opentelemetry-instrumentation-click/README.rst new file mode 100644 index 0000000000..bb7ae97147 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/README.rst @@ -0,0 +1,24 @@ +OpenTelemetry click Instrumentation +=========================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-click.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-click/ + +This library allows tracing requests made by the click library. + +Installation +------------ + + +:: + + pip install opentelemetry-instrumentation-click + + +References +---------- + +* `OpenTelemetry click/ Tracing `_ +* `OpenTelemetry Project `_ diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml new file mode 100644 index 0000000000..d5b8e71830 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -0,0 +1,54 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-click" +dynamic = ["version"] +description = "Click instrumentation for OpenTelemetry" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.8" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "opentelemetry-api ~= 1.12", + "opentelemetry-semantic-conventions == 0.50b0.dev", + "wrapt >= 1.0.0, < 2.0.0", +] + +[project.optional-dependencies] +instruments = [ + "click >= 8.1.3, < 9.0.0", +] + +[project.entry-points.opentelemetry_instrumentor] +click = "opentelemetry.instrumentation.click:ClickInstrumentor" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-click" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/click/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py new file mode 100644 index 0000000000..8222bfdf5a --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py @@ -0,0 +1,122 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Instrument `click`_ CLI applications. + +.. _click: https://pypi.org/project/click/ + +Usage +----- + +.. code-block:: python + + import click + from opentelemetry.instrumentation.click import ClickInstrumentor + + ClickInstrumentor().instrument() + + @click.command() + def hello(): + click.echo(f'Hello world!') + + if __name__ == "__main__": + hello() + +API +--- +""" + +import os +import sys +from functools import partial +from logging import getLogger +from typing import Collection + +import click +from wrapt import wrap_function_wrapper + +from opentelemetry import trace +from opentelemetry.instrumentation.click.package import _instruments +from opentelemetry.instrumentation.click.version import __version__ +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.instrumentation.utils import ( + unwrap, +) +from opentelemetry.semconv._incubating.attributes.process_attributes import ( + PROCESS_COMMAND_ARGS, + PROCESS_EXECUTABLE_NAME, + PROCESS_EXIT_CODE, + PROCESS_PID, +) +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.trace.status import StatusCode + +_logger = getLogger(__name__) + + +def _command_invoke_wrapper(wrapped, instance, args, kwargs, tracer): + # Subclasses of Command include groups and CLI runners, but + # we only want to instrument the actual commands which are + # instances of Command itself. + if instance.__class__ != click.Command: + return wrapped(*args, **kwargs) + + ctx = args[0] + span_name = ctx.info_name + span_attributes = { + PROCESS_COMMAND_ARGS: sys.argv, + PROCESS_EXECUTABLE_NAME: sys.argv[0], + PROCESS_EXIT_CODE: 0, + PROCESS_PID: os.getpid(), + } + + with tracer.start_as_current_span( + name=span_name, + kind=trace.SpanKind.INTERNAL, + attributes=span_attributes, + ) as span: + try: + return wrapped(*args, **kwargs) + except Exception as exc: + span.set_status(StatusCode.ERROR, str(exc)) + if span.is_recording(): + span.set_attribute(ERROR_TYPE, exc.__class__.__qualname__) + span.set_attribute( + PROCESS_EXIT_CODE, getattr(exc, "exit_code", 1) + ) + raise + + +class ClickInstrumentor(BaseInstrumentor): + """An instrumentor for click""" + + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs): + tracer = trace.get_tracer( + __name__, + __version__, + kwargs.get("tracer_provider"), + ) + + wrap_function_wrapper( + click.core.Command, + "invoke", + partial(_command_invoke_wrapper, tracer=tracer), + ) + + def _uninstrument(self, **kwargs): + unwrap(click.core.Command, "invoke") diff --git a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/package.py b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/package.py new file mode 100644 index 0000000000..6e0a1db2b5 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/package.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +_instruments = ("click >= 8.1.3, < 9.0.0",) diff --git a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py new file mode 100644 index 0000000000..0559ba6227 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "0.50b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt new file mode 100644 index 0000000000..6e9162ccde --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt @@ -0,0 +1,15 @@ +asgiref==3.8.1 +click==8.1.7 +Deprecated==1.2.14 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +pytest-asyncio==0.23.5 +tomli==2.0.1 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-click diff --git a/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py b/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py new file mode 100644 index 0000000000..41d01a5bb4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py @@ -0,0 +1,176 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from unittest import mock + +import click +from click.testing import CliRunner + +from opentelemetry.instrumentation.click import ClickInstrumentor +from opentelemetry.test.test_base import TestBase +from opentelemetry.trace import SpanKind +from opentelemetry.trace.status import StatusCode + + +class ClickTestCase(TestBase): + # pylint: disable=unbalanced-tuple-unpacking + def setUp(self): + super().setUp() + + ClickInstrumentor().instrument() + + def tearDown(self): + super().tearDown() + ClickInstrumentor().uninstrument() + + @mock.patch("sys.argv", ["command.py"]) + def test_cli_command_wrapping(self): + @click.command() + def command(): + pass + + runner = CliRunner() + result = runner.invoke(command) + self.assertEqual(result.exit_code, 0) + + (span,) = self.memory_exporter.get_finished_spans() + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.kind, SpanKind.INTERNAL) + self.assertEqual(span.name, "command") + self.assertEqual( + dict(span.attributes), + { + "process.executable.name": "command.py", + "process.command_args": ("command.py",), + "process.exit.code": 0, + "process.pid": os.getpid(), + }, + ) + + @mock.patch("sys.argv", ["flask", "command"]) + def test_flask_run_command_wrapping(self): + @click.command() + def command(): + pass + + runner = CliRunner() + result = runner.invoke(command) + self.assertEqual(result.exit_code, 0) + + (span,) = self.memory_exporter.get_finished_spans() + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.kind, SpanKind.INTERNAL) + self.assertEqual(span.name, "command") + self.assertEqual( + dict(span.attributes), + { + "process.executable.name": "flask", + "process.command_args": ( + "flask", + "command", + ), + "process.exit.code": 0, + "process.pid": os.getpid(), + }, + ) + + @mock.patch("sys.argv", ["command.py"]) + def test_cli_command_wrapping_with_name(self): + @click.command("mycommand") + def renamedcommand(): + pass + + runner = CliRunner() + result = runner.invoke(renamedcommand) + self.assertEqual(result.exit_code, 0) + + (span,) = self.memory_exporter.get_finished_spans() + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.kind, SpanKind.INTERNAL) + self.assertEqual(span.name, "mycommand") + self.assertEqual( + dict(span.attributes), + { + "process.executable.name": "command.py", + "process.command_args": ("command.py",), + "process.exit.code": 0, + "process.pid": os.getpid(), + }, + ) + + @mock.patch("sys.argv", ["command.py", "--opt", "argument"]) + def test_cli_command_wrapping_with_options(self): + @click.command() + @click.argument("argument") + @click.option("--opt/--no-opt", default=False) + def command(argument, opt): + pass + + argv = ["command.py", "--opt", "argument"] + runner = CliRunner() + result = runner.invoke(command, argv[1:]) + self.assertEqual(result.exit_code, 0) + + (span,) = self.memory_exporter.get_finished_spans() + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual(span.kind, SpanKind.INTERNAL) + self.assertEqual(span.name, "command") + self.assertEqual( + dict(span.attributes), + { + "process.executable.name": "command.py", + "process.command_args": tuple(argv), + "process.exit.code": 0, + "process.pid": os.getpid(), + }, + ) + + @mock.patch("sys.argv", ["command-raises.py"]) + def test_cli_command_raises_error(self): + @click.command() + def command_raises(): + raise ValueError() + + runner = CliRunner() + result = runner.invoke(command_raises) + self.assertEqual(result.exit_code, 1) + + (span,) = self.memory_exporter.get_finished_spans() + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual(span.kind, SpanKind.INTERNAL) + self.assertEqual(span.name, "command-raises") + self.assertEqual( + dict(span.attributes), + { + "process.executable.name": "command-raises.py", + "process.command_args": ("command-raises.py",), + "process.exit.code": 1, + "process.pid": os.getpid(), + "error.type": "ValueError", + }, + ) + + def test_uninstrument(self): + ClickInstrumentor().uninstrument() + + @click.command() + def notracecommand(): + pass + + runner = CliRunner() + result = runner.invoke(notracecommand) + self.assertEqual(result.exit_code, 0) + + self.assertFalse(self.memory_exporter.get_finished_spans()) diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 11eae92ba6..a0edde1390 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -43,6 +43,7 @@ dependencies = [ "opentelemetry-instrumentation-botocore==0.50b0.dev", "opentelemetry-instrumentation-cassandra==0.50b0.dev", "opentelemetry-instrumentation-celery==0.50b0.dev", + "opentelemetry-instrumentation-click==0.50b0.dev", "opentelemetry-instrumentation-confluent-kafka==0.50b0.dev", "opentelemetry-instrumentation-dbapi==0.50b0.dev", "opentelemetry-instrumentation-django==0.50b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 6b7eae6b00..a292299d70 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -72,6 +72,10 @@ "library": "celery >= 4.0, < 6.0", "instrumentation": "opentelemetry-instrumentation-celery==0.50b0.dev", }, + { + "library": "click >= 8.1.3, < 9.0.0", + "instrumentation": "opentelemetry-instrumentation-click==0.50b0.dev", + }, { "library": "confluent-kafka >= 1.8.2, <= 2.4.0", "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.50b0.dev", diff --git a/tox.ini b/tox.ini index cc5e509abc..5fa58e5139 100644 --- a/tox.ini +++ b/tox.ini @@ -94,6 +94,11 @@ envlist = ; pypy3-test-instrumentation-boto lint-instrumentation-boto + ; opentelemetry-instrumentation-click + py3{8,9,10,11,12}-test-instrumentation-click + pypy3-test-instrumentation-click + lint-instrumentation-click + ; opentelemetry-instrumentation-elasticsearch ; The numbers at the end of the environment names ; below mean these dependencies are being used: @@ -443,6 +448,12 @@ commands_pre = pypy3-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt lint-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt + click: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + click: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + click: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + click: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + click: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt + sio-pika: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api sio-pika: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions sio-pika: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -876,6 +887,9 @@ commands = test-instrumentation-celery: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/tests {posargs} lint-instrumentation-celery: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-celery" + test-instrumentation-click: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-click/tests {posargs} + lint-instrumentation-click: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-click" + test-instrumentation-dbapi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/tests {posargs} lint-instrumentation-dbapi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-dbapi" From af8d0930ca0edbc97d10afab5aa1d958fd925244 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 28 Nov 2024 17:40:15 +0100 Subject: [PATCH 255/335] opentelemetry-instrumentation-openai-v2: pin httpx dependency (#3056) As 0.28.0 broke compat with old openai client. --- .../test-requirements-0.txt | 1 + .../test-requirements-1.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt index 5e1693b69a..a68dbbf744 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt @@ -1,5 +1,6 @@ openai==1.26.0 pydantic==2.8.2 +httpx==0.27.2 Deprecated==1.2.14 importlib-metadata==6.11.0 packaging==24.0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt index 618410edd3..6725ed7b66 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt @@ -1,5 +1,6 @@ openai==1.26.0 pydantic==2.8.2 +httpx==0.27.2 Deprecated==1.2.14 importlib-metadata==6.11.0 packaging==24.0 From 8656a06f880b8e5aaf4a51e0db968b735304836d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:07:52 -0300 Subject: [PATCH 256/335] try update misc workflows to py311 (#3055) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .../src/generate_workflows_lib/misc.yml.j2 | 4 +-- .github/workflows/misc_0.yml | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index add97c645a..9972507bb6 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -51,10 +51,10 @@ jobs: run: git checkout ${% raw %}{{ github.event.pull_request.head.sha }}{% endraw %} {%- endif %} - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index ca94a69563..1148f85abd 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -23,10 +23,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox @@ -41,10 +41,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox @@ -61,10 +61,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox @@ -79,10 +79,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox @@ -103,10 +103,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox @@ -124,10 +124,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox @@ -142,10 +142,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox From 142b86c1bf2b45118f159b8f29217c3ea7815160 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 2 Dec 2024 01:23:11 -0800 Subject: [PATCH 257/335] OpenAI instrumentation docs fixes (#2988) * Add openai docs config and improve readme * up * Add manual sample, add no-content tests * update headers * lint * use grpc endpoint in openai samples, add extra env vars to readme * move distro fix to another PR * nits * Ignore examples for pylint * Update .pylintrc * ignroe lint for example * Fix README docs * Update openai.rst * Update conf.py * Update docs-requirements.txt * docs --------- Co-authored-by: Leighton Chen Co-authored-by: Riccardo Magliocchetti --- docs-requirements.txt | 3 +- docs/conf.py | 16 ++- docs/index.rst | 11 +- docs/instrumentation-genai/openai.rst | 7 + docs/nitpick-exceptions.ini | 1 + .../README.rst | 56 +++++++- .../examples/manual/.env | 16 +++ .../{example => examples/manual}/README.rst | 13 +- .../examples/manual/main.py | 53 +++++++ .../examples/manual/requirements.txt | 5 + .../{example => examples/zero-code}/.env | 9 +- .../examples/zero-code/README.rst | 48 +++++++ .../{example => examples/zero-code}/main.py | 0 .../zero-code}/requirements.txt | 2 +- .../pyproject.toml | 2 +- .../test-requirements-0.txt | 1 + ...test_async_chat_completion_no_content.yaml | 132 +++++++++++++++++ .../test_chat_completion_no_content.yaml | 134 ++++++++++++++++++ .../tests/conftest.py | 5 + .../tests/test_async_chat_completions.py | 28 ++++ .../tests/test_chat_completions.py | 27 ++++ 21 files changed, 555 insertions(+), 14 deletions(-) create mode 100644 docs/instrumentation-genai/openai.rst create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/.env rename instrumentation-genai/opentelemetry-instrumentation-openai-v2/{example => examples/manual}/README.rst (67%) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/main.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt rename instrumentation-genai/opentelemetry-instrumentation-openai-v2/{example => examples/zero-code}/.env (65%) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/README.rst rename instrumentation-genai/opentelemetry-instrumentation-openai-v2/{example => examples/zero-code}/main.py (100%) rename instrumentation-genai/opentelemetry-instrumentation-openai-v2/{example => examples/zero-code}/requirements.txt (71%) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_no_content.yaml diff --git a/docs-requirements.txt b/docs-requirements.txt index 6342594af3..43e2265f7c 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -33,9 +33,11 @@ elasticsearch>=6.0,<9.0 flask~=2.0 falcon~=2.0 grpcio~=1.27 +httpx>=0.18.0 kafka-python>=2.0,<3.0 mysql-connector-python~=8.0 mysqlclient~=2.1.1 +openai >= 1.26.0 psutil>=5 psycopg~=3.1.17 pika>=0.12.0 @@ -47,7 +49,6 @@ remoulade>=0.50 sqlalchemy>=1.0 tornado>=5.1.1 tortoise-orm>=0.17.0 -httpx>=0.18.0 # indirect dependency pins markupsafe==2.0.1 diff --git a/docs/conf.py b/docs/conf.py index 4b2bda04a8..8233fccb15 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -40,6 +40,13 @@ if isdir(join(instr, f)) ] +instr_genai = "../instrumentation-genai" +instr_genai_dirs = [ + os.path.abspath("/".join(["../instrumentation-genai", f, "src"])) + for f in listdir(instr_genai) + if isdir(join(instr_genai, f)) +] + prop = "../propagator" prop_dirs = [ os.path.abspath("/".join([prop, f, "src"])) @@ -60,7 +67,14 @@ for f in listdir(resource) if isdir(join(resource, f)) ] -sys.path[:0] = exp_dirs + instr_dirs + sdk_ext_dirs + prop_dirs + resource_dirs +sys.path[:0] = ( + exp_dirs + + instr_dirs + + instr_genai_dirs + + sdk_ext_dirs + + prop_dirs + + resource_dirs +) # -- Project information ----------------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index e2bf32e12e..f9144c5209 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,7 +24,7 @@ installed separately via pip: pip install opentelemetry-instrumentation-{instrumentation} pip install opentelemetry-sdk-extension-{sdk-extension} -A complete list of packages can be found at the +A complete list of packages can be found at the `Contrib repo instrumentation `_ and `Contrib repo exporter `_ directories. @@ -50,6 +50,7 @@ install cd opentelemetry-python-contrib pip install -e ./instrumentation/opentelemetry-instrumentation-flask pip install -e ./instrumentation/opentelemetry-instrumentation-botocore + pip install -e ./instrumentation-genai/opentelemetry-instrumentation-openai-v2 pip install -e ./sdk-extension/opentelemetry-sdk-extension-aws pip install -e ./resource/opentelemetry-resource-detector-container @@ -62,6 +63,14 @@ install instrumentation/** +.. toctree:: + :maxdepth: 2 + :caption: OpenTelemetry Generative AI Instrumentations + :name: Generative AI Instrumentations + :glob: + + instrumentation-genai/** + .. toctree:: :maxdepth: 2 :caption: OpenTelemetry Propagators diff --git a/docs/instrumentation-genai/openai.rst b/docs/instrumentation-genai/openai.rst new file mode 100644 index 0000000000..71f464c533 --- /dev/null +++ b/docs/instrumentation-genai/openai.rst @@ -0,0 +1,7 @@ +OpenTelemetry Python - OpenAI Instrumentation +============================================= + +.. automodule:: opentelemetry.instrumentation.openai_v2 + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index 9dc379cf93..845883fdd8 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -24,6 +24,7 @@ py-class= httpx.Client httpx.AsyncClient httpx.BaseTransport + openai.BaseTransport httpx.AsyncBaseTransport httpx.SyncByteStream httpx.AsyncByteStream diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst index bbd142a97e..d2cb0b5724 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst @@ -19,8 +19,60 @@ package to your requirements. pip install opentelemetry-instrumentation-openai-v2 -If you don't have an OpenAI application, yet, try our `example `_ -which only needs a valid OpenAI API key. +If you don't have an OpenAI application, yet, try our `examples `_ +which only need a valid OpenAI API key. + +Check out `zero-code example `_ for a quick start. + +Usage +----- + +This section describes how to set up OpenAI instrumentation if you're setting OpenTelemetry up manually. +Check out the `manual example `_ for more details. + +Instrumenting all clients +************************* + +When using the instrumentor, all clients will automatically trace OpenAI chat completion operations. +You can also optionally capture prompts and completions as log events. + +Make sure to configure OpenTelemetry tracing, logging, and events to capture all telemetry emitted by the instrumentation. + +.. code-block:: python + + from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor + + OpenAIInstrumentor().instrument() + + client = OpenAI() + response = client.chat.completions.create( + model="gpt-4o-mini", + messages=[ + {"role": "user", "content": "Write a short poem on open telemetry."}, + ], + ) + +Enabling message content +************************* + +Message content such as the contents of the prompt, completion, function arguments and return values +are not captured by default. To capture message content as log events, set the environment variable +`OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` to `true`. + +Uninstrument +************ + +To uninstrument clients, call the uninstrument method: + +.. code-block:: python + + from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor + + OpenAIInstrumentor().instrument() + # ... + + # Uninstrument all clients + OpenAIInstrumentor().uninstrument() References ---------- diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/.env b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/.env new file mode 100644 index 0000000000..1e77ee78c0 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/.env @@ -0,0 +1,16 @@ +# Update this with your real OpenAI API key +OPENAI_API_KEY=sk-YOUR_API_KEY + +# Uncomment to use Ollama instead of OpenAI +# OPENAI_BASE_URL=http://localhost:11434/v1 +# OPENAI_API_KEY=unused +# CHAT_MODEL=qwen2.5:0.5b + +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + +OTEL_SERVICE_NAME=opentelemetry-python-openai + +# Change to 'false' to hide prompt and completion content +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/README.rst similarity index 67% rename from instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/README.rst index 019e141c70..73e4d1bb0c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/README.rst +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/README.rst @@ -1,8 +1,7 @@ OpenTelemetry OpenAI Instrumentation Example ============================================ -This is an example of how to instrument OpenAI calls with zero code changes, -using `opentelemetry-instrument`. +This is an example of how to instrument OpenAI calls when configuring OpenTelemetry SDK and Instrumentations manually. When `main.py `_ is run, it exports traces and logs to an OTLP compatible endpoint. Traces include details such as the model used and the @@ -10,12 +9,18 @@ duration of the chat request. Logs capture the chat request and the generated response, providing a comprehensive view of the performance and behavior of your OpenAI requests. +Note: `.env <.env>`_ file configures additional environment variables: + +- `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true` configures +OpenAI instrumentation to capture prompt and completion contents on +events. + Setup ----- Minimally, update the `.env <.env>`_ file with your "OPENAI_API_KEY". An OTLP compatible endpoint should be listening for traces and logs on -http://localhost:4318. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. +http://localhost:4317. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. Next, set up a virtual environment like this: @@ -33,7 +38,7 @@ Run the example like this: :: - dotenv run -- opentelemetry-instrument python main.py + dotenv run -- python main.py You should see a poem generated by OpenAI while traces and logs export to your configured observability tool. diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/main.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/main.py new file mode 100644 index 0000000000..4b0c121b7a --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/main.py @@ -0,0 +1,53 @@ +# pylint: skip-file +import os + +from openai import OpenAI + +# NOTE: OpenTelemetry Python Logs and Events APIs are in beta +from opentelemetry import _events, _logs, trace +from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( + OTLPLogExporter, +) +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter, +) +from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import BatchLogRecordProcessor +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +# configure tracing +trace.set_tracer_provider(TracerProvider()) +trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(OTLPSpanExporter()) +) + +# configure logging and events +_logs.set_logger_provider(LoggerProvider()) +_logs.get_logger_provider().add_log_record_processor( + BatchLogRecordProcessor(OTLPLogExporter()) +) +_events.set_event_logger_provider(EventLoggerProvider()) + +# instrument OpenAI +OpenAIInstrumentor().instrument() + + +def main(): + client = OpenAI() + chat_completion = client.chat.completions.create( + model=os.getenv("CHAT_MODEL", "gpt-4o-mini"), + messages=[ + { + "role": "user", + "content": "Write a short poem on OpenTelemetry.", + }, + ], + ) + print(chat_completion.choices[0].message.content) + + +if __name__ == "__main__": + main() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt new file mode 100644 index 0000000000..436f63e1d5 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt @@ -0,0 +1,5 @@ +openai~=1.54.4 + +opentelemetry-sdk~=1.28.2 +opentelemetry-exporter-otlp-proto-grpc~=1.28.2 +opentelemetry-instrumentation-openai-v2~=2.0b0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env similarity index 65% rename from instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env index d6afa66723..7dfa745e3b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/.env +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env @@ -6,13 +6,16 @@ OPENAI_API_KEY=sk-YOUR_API_KEY # OPENAI_API_KEY=unused # CHAT_MODEL=qwen2.5:0.5b -OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 -OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + OTEL_SERVICE_NAME=opentelemetry-python-openai # Change to 'false' to disable logging OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true # Change to 'console' if your OTLP endpoint doesn't support logs -OTEL_LOGS_EXPORTER=otlp_proto_http +# TODO: this should not be necessary once https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3042 is released +OTEL_LOGS_EXPORTER=otlp # Change to 'false' to hide prompt and completion content OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/README.rst new file mode 100644 index 0000000000..441c6a612e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/README.rst @@ -0,0 +1,48 @@ +OpenTelemetry OpenAI Zero-Code Instrumentation Example +====================================================== + +This is an example of how to instrument OpenAI calls with zero code changes, +using `opentelemetry-instrument`. + +When `main.py `_ is run, it exports traces and logs to an OTLP +compatible endpoint. Traces include details such as the model used and the +duration of the chat request. Logs capture the chat request and the generated +response, providing a comprehensive view of the performance and behavior of +your OpenAI requests. + +Note: `.env <.env>`_ file configures additional environment variables: + +- `OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true` configures +OpenTelemetry SDK to export logs and events. +- `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true` configures +OpenAI instrumentation to capture prompt and completion contents on +events. +- `OTEL_LOGS_EXPORTER=otlp` to specify exporter type. + +Setup +----- + +Minimally, update the `.env <.env>`_ file with your "OPENAI_API_KEY". An +OTLP compatible endpoint should be listening for traces and logs on +http://localhost:4317. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example like this: + +:: + + dotenv run -- opentelemetry-instrument python main.py + +You should see a poem generated by OpenAI while traces and logs export to your +configured observability tool. diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/main.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/main.py similarity index 100% rename from instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/main.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/main.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt similarity index 71% rename from instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt index 9ec9bff320..77ed112ebb 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/example/requirements.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt @@ -1,6 +1,6 @@ openai~=1.54.4 opentelemetry-sdk~=1.28.2 -opentelemetry-exporter-otlp-proto-http~=1.28.2 +opentelemetry-exporter-otlp-proto-grpc~=1.28.2 opentelemetry-distro~=0.49b2 opentelemetry-instrumentation-openai-v2~=2.0b0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index e28611d0c5..f37b6915e3 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -39,7 +39,7 @@ instruments = [ openai = "opentelemetry.instrumentation.openai_v2:OpenAIInstrumentor" [project.urls] -Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-openai-v2" +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-openai-v2" [tool.hatch.version] path = "src/opentelemetry/instrumentation/openai_v2/version.py" diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt index a68dbbf744..bd22b7a870 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt @@ -8,6 +8,7 @@ pytest==7.4.4 pytest-vcr==1.0.2 pytest-asyncio==0.21.0 wrapt==1.16.0 +opentelemetry-exporter-otlp-proto-http~=1.28 opentelemetry-api==1.28 # when updating, also update in pyproject.toml opentelemetry-sdk==1.28 # when updating, also update in pyproject.toml opentelemetry-semantic-conventions==0.49b0 # when updating, also update in pyproject.toml diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_no_content.yaml new file mode 100644 index 0000000000..61ec4a646e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_no_content.yaml @@ -0,0 +1,132 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9R2E7Yhb2e7bj4Xl0qm9s3J42Y", + "object": "chat.completion", + "created": 1731456237, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80679a8311a6-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:03:58 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '796' + openai-organization: test_openai_org_id + openai-processing-ms: + - '359' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999978' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_41ea134c1fc450d4ca4cf8d0c6a7c53a + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_no_content.yaml new file mode 100644 index 0000000000..2abb443fe3 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_no_content.yaml @@ -0,0 +1,134 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMQRl3A3DXL9FWCK9tnGRcKIO7q", + "object": "chat.completion", + "created": 1731368630, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 5, + "total_tokens": 17, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e122593ff368bc8-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:50 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '765' + openai-organization: test_openai_org_id + openai-processing-ms: + - '287' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '199977' + x-ratelimit-reset-requests: + - 8.64s + x-ratelimit-reset-tokens: + - 6ms + x-request-id: + - req_58cff97afd0e7c0bba910ccf0b044a6f + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 7ff7e46777..18e6582dff 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -84,6 +84,10 @@ def vcr_config(): @pytest.fixture(scope="function") def instrument_no_content(tracer_provider, event_logger_provider): + os.environ.update( + {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"} + ) + instrumentor = OpenAIInstrumentor() instrumentor.instrument( tracer_provider=tracer_provider, @@ -91,6 +95,7 @@ def instrument_no_content(tracer_provider, event_logger_provider): ) yield instrumentor + os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) instrumentor.uninstrument() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py index 1c4b3cb7dd..e19bc7c311 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py @@ -68,6 +68,34 @@ async def test_async_chat_completion_with_content( assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_no_content( + span_exporter, log_exporter, async_openai_client, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + assert_message_in_logs(logs[0], "gen_ai.user.message", None, spans[0]) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant"}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + @pytest.mark.asyncio() async def test_async_chat_completion_bad_endpoint( span_exporter, instrument_no_content diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index c6cb19aa8d..4f732290c0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -67,6 +67,33 @@ def test_chat_completion_with_content( assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) +@pytest.mark.vcr() +def test_chat_completion_no_content( + span_exporter, log_exporter, openai_client, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + assert_message_in_logs(logs[0], "gen_ai.user.message", None, spans[0]) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant"}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): llm_model_value = "gpt-4o-mini" messages_value = [{"role": "user", "content": "Say this is a test"}] From 0da62aa532e402db1c8bec854c502280f577345e Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 3 Dec 2024 04:28:45 +0100 Subject: [PATCH 258/335] Add type hints to Starlette instrumentation (#3045) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add type hints to Starlette instrumentation * format * Add changelog * Add changelog * Remove pyright ignore --------- Co-authored-by: Riccardo Magliocchetti Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- CHANGELOG.md | 2 + .../opentelemetry/instrumentation/py.typed | 0 .../instrumentation/starlette/__init__.py | 68 ++++++++++++------- 3 files changed, 44 insertions(+), 26 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index a28c5039c9..4198628292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-starlette` Add type hints to the instrumentation + ([#3045](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3045)) - `opentelemetry-distro` default to OTLP log exporter. ([#3042](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3042)) - `opentelemetry-instrumentation-sqlalchemy` Update unit tests to run with SQLALchemy 2 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/py.typed b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index 820fa29411..5007bda50a 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -170,7 +170,9 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A --- """ -from typing import Collection +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Collection, cast from starlette import applications from starlette.routing import Match @@ -184,18 +186,29 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.starlette.package import _instruments from opentelemetry.instrumentation.starlette.version import __version__ -from opentelemetry.metrics import get_meter +from opentelemetry.metrics import MeterProvider, get_meter from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import get_tracer +from opentelemetry.trace import TracerProvider, get_tracer from opentelemetry.util.http import get_excluded_urls +if TYPE_CHECKING: + from typing import TypedDict, Unpack + + class InstrumentKwargs(TypedDict, total=False): + tracer_provider: TracerProvider + meter_provider: MeterProvider + server_request_hook: ServerRequestHook + client_request_hook: ClientRequestHook + client_response_hook: ClientResponseHook + + _excluded_urls = get_excluded_urls("STARLETTE") class StarletteInstrumentor(BaseInstrumentor): - """An instrumentor for starlette + """An instrumentor for Starlette. - See `BaseInstrumentor` + See `BaseInstrumentor`. """ _original_starlette = None @@ -206,8 +219,8 @@ def instrument_app( server_request_hook: ServerRequestHook = None, client_request_hook: ClientRequestHook = None, client_response_hook: ClientResponseHook = None, - meter_provider=None, - tracer_provider=None, + meter_provider: MeterProvider | None = None, + tracer_provider: TracerProvider | None = None, ): """Instrument an uninstrumented Starlette application.""" tracer = get_tracer( @@ -253,7 +266,7 @@ def uninstrument_app(app: applications.Starlette): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Unpack[InstrumentKwargs]): self._original_starlette = applications.Starlette _InstrumentedStarlette._tracer_provider = kwargs.get("tracer_provider") _InstrumentedStarlette._server_request_hook = kwargs.get( @@ -269,7 +282,7 @@ def _instrument(self, **kwargs): applications.Starlette = _InstrumentedStarlette - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): """uninstrumenting all created apps by user""" for instance in _InstrumentedStarlette._instrumented_starlette_apps: self.uninstrument_app(instance) @@ -278,14 +291,14 @@ def _uninstrument(self, **kwargs): class _InstrumentedStarlette(applications.Starlette): - _tracer_provider = None - _meter_provider = None + _tracer_provider: TracerProvider | None = None + _meter_provider: MeterProvider | None = None _server_request_hook: ServerRequestHook = None _client_request_hook: ClientRequestHook = None _client_response_hook: ClientResponseHook = None - _instrumented_starlette_apps = set() + _instrumented_starlette_apps: set[applications.Starlette] = set() - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any): super().__init__(*args, **kwargs) tracer = get_tracer( __name__, @@ -318,21 +331,22 @@ def __del__(self): _InstrumentedStarlette._instrumented_starlette_apps.remove(self) -def _get_route_details(scope): +def _get_route_details(scope: dict[str, Any]) -> str | None: """ - Function to retrieve Starlette route from scope. + Function to retrieve Starlette route from ASGI scope. TODO: there is currently no way to retrieve http.route from a starlette application from scope. See: https://github.com/encode/starlette/pull/804 Args: - scope: A Starlette scope + scope: The ASGI scope that contains the Starlette application in the "app" key. + Returns: - A string containing the route or None + The path to the route if found, otherwise None. """ - app = scope["app"] - route = None + app = cast(applications.Starlette, scope["app"]) + route: str | None = None for starlette_route in app.routes: match, _ = starlette_route.matches(scope) @@ -344,18 +358,20 @@ def _get_route_details(scope): return route -def _get_default_span_details(scope): - """ - Callback to retrieve span name and attributes from scope. +def _get_default_span_details( + scope: dict[str, Any], +) -> tuple[str, dict[str, Any]]: + """Callback to retrieve span name and attributes from ASGI scope. Args: - scope: A Starlette scope + scope: The ASGI scope that contains the Starlette application in the "app" key. + Returns: - A tuple of span name and attributes + A tuple of span name and attributes. """ route = _get_route_details(scope) - method = scope.get("method", "") - attributes = {} + method: str = scope.get("method", "") + attributes: dict[str, Any] = {} if route: attributes[SpanAttributes.HTTP_ROUTE] = route if method and route: # http From 668cb75f247cdb2a620b4f4871d6a122e9d567d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 3 Dec 2024 06:19:43 -0300 Subject: [PATCH 259/335] docs: add missing autodoc for click and aiohttp-server (#3060) * add missing docs for click and aiohttp-server Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix click readme Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * add nitpick Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- docs/instrumentation/aiohttp_server/aiohttp_server.rst | 7 +++++++ docs/instrumentation/click/click.rst | 7 +++++++ docs/nitpick-exceptions.ini | 3 ++- .../opentelemetry-instrumentation-click/README.rst | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 docs/instrumentation/aiohttp_server/aiohttp_server.rst create mode 100644 docs/instrumentation/click/click.rst diff --git a/docs/instrumentation/aiohttp_server/aiohttp_server.rst b/docs/instrumentation/aiohttp_server/aiohttp_server.rst new file mode 100644 index 0000000000..a4de9c4eaa --- /dev/null +++ b/docs/instrumentation/aiohttp_server/aiohttp_server.rst @@ -0,0 +1,7 @@ +.. include:: ../../../instrumentation/opentelemetry-instrumentation-aiohttp-server/README.rst + :end-before: References + +.. automodule:: opentelemetry.instrumentation.aiohttp_server + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/instrumentation/click/click.rst b/docs/instrumentation/click/click.rst new file mode 100644 index 0000000000..61da603a7c --- /dev/null +++ b/docs/instrumentation/click/click.rst @@ -0,0 +1,7 @@ +.. include:: ../../../instrumentation/opentelemetry-instrumentation-click/README.rst + :end-before: References + +.. automodule:: opentelemetry.instrumentation.click + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index 845883fdd8..4b1b06f95b 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -29,6 +29,7 @@ py-class= httpx.SyncByteStream httpx.AsyncByteStream httpx.Response + aiohttp.web_request.Request yarl.URL cimpl.Producer cimpl.Consumer @@ -65,7 +66,7 @@ any= py-obj= opentelemetry.propagators.textmap.CarrierT - + py-func= poll flush diff --git a/instrumentation/opentelemetry-instrumentation-click/README.rst b/instrumentation/opentelemetry-instrumentation-click/README.rst index bb7ae97147..4dde08a99a 100644 --- a/instrumentation/opentelemetry-instrumentation-click/README.rst +++ b/instrumentation/opentelemetry-instrumentation-click/README.rst @@ -1,5 +1,5 @@ OpenTelemetry click Instrumentation -=========================== +==================================== |pypi| From b6541f0bada9a0569a858337e2df27d5f6f3032a Mon Sep 17 00:00:00 2001 From: Rytis Bagdziunas Date: Tue, 3 Dec 2024 10:31:08 +0100 Subject: [PATCH 260/335] Remove references to disposed SQLAlchemy engines from instrumentation singleton (#3053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove references to SQLAlchemy engines which are disposed of EngineTracer in SQLAlchemy keeps weak references to a traced engine forever which can cause a noticeable memory leak if engines are constantly getting creating. * Updated changelog --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../instrumentation/sqlalchemy/engine.py | 13 +++++++++++++ .../tests/test_sqlalchemy.py | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4198628292..0a1039f83a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022)) - Replace all instrumentor unit test `assertEqualSpanInstrumentationInfo` calls with `assertEqualSpanInstrumentationScope` calls ([#3037](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3037)) +- `opentelemetry-instrumentation-sqlalchemy`: Fix a remaining memory leak in EngineTracer + ([#3053](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3053)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py index b64af796d1..a20e481819 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py @@ -167,6 +167,13 @@ def _pool_checkout( self._add_idle_to_connection_usage(-1) self._add_used_to_connection_usage(1) + @classmethod + def _dispose_of_event_listener(cls, obj): + try: + cls._remove_event_listener_params.remove(obj) + except ValueError: + pass + @classmethod def _register_event_listener(cls, target, identifier, func, *args, **kw): listen(target, identifier, func, *args, **kw) @@ -174,6 +181,12 @@ def _register_event_listener(cls, target, identifier, func, *args, **kw): (weakref.ref(target), identifier, func) ) + weakref.finalize( + target, + cls._dispose_of_event_listener, + (weakref.ref(target), identifier, func), + ) + @classmethod def remove_all_event_listeners(cls): for ( diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py index 957ae16237..18b9fa65f7 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py @@ -417,6 +417,10 @@ def test_no_memory_leakage_if_engine_diposed(self): from sqlalchemy import create_engine + from opentelemetry.instrumentation.sqlalchemy.engine import ( + EngineTracer, + ) + callback = mock.Mock() def make_shortlived_engine(): @@ -432,3 +436,4 @@ def make_shortlived_engine(): gc.collect() assert callback.call_count == 5 + assert len(EngineTracer._remove_event_listener_params) == 0 From 9e83e25441342fba795b35c225d518034644779e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:03:23 -0300 Subject: [PATCH 261/335] test two requirements files for docs and rtd (#3039) --- .readthedocs.yml | 2 +- docs-requirements.txt | 8 -------- rtd-requirements.txt | 7 +++++++ 3 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 rtd-requirements.txt diff --git a/.readthedocs.yml b/.readthedocs.yml index 2a3c920b45..dcf3204080 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -12,4 +12,4 @@ build: python: install: - - requirements: docs-requirements.txt + - requirements: rtd-requirements.txt diff --git a/docs-requirements.txt b/docs-requirements.txt index 43e2265f7c..d547e806a3 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -2,14 +2,6 @@ sphinx==7.1.2 sphinx-rtd-theme==2.0.0rc4 sphinx-autodoc-typehints==1.25.2 -# Need to install the api/sdk in the venv for autodoc. Modifying sys.path -# doesn't work for pkg_resources. --e "git+https://github.com/open-telemetry/opentelemetry-python.git#egg=opentelemetry-api&subdirectory=opentelemetry-api" --e "git+https://github.com/open-telemetry/opentelemetry-python.git#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions" --e "git+https://github.com/open-telemetry/opentelemetry-python.git#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk" --e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-util-http&subdirectory=util/opentelemetry-util-http" -./opentelemetry-instrumentation - # Required by opentelemetry-instrumentation fastapi>=0.65.2 pymemcache~=1.3 diff --git a/rtd-requirements.txt b/rtd-requirements.txt new file mode 100644 index 0000000000..b68781bd8c --- /dev/null +++ b/rtd-requirements.txt @@ -0,0 +1,7 @@ +# Need to install the api/sdk in the venv for autodoc. Used by .readthedocs.yml +opentelemetry-api @ git+https://github.com/open-telemetry/opentelemetry-python.git@main#egg=opentelemetry-api&subdirectory=opentelemetry-api +opentelemetry-semantic-conventions @ git+https://github.com/open-telemetry/opentelemetry-python.git@main#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions +opentelemetry-sdk @ git+https://github.com/open-telemetry/opentelemetry-python.git@main#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk +./opentelemetry-instrumentation +./util/opentelemetry-util-http +-r ./docs-requirements.txt From 76170313f162a3a5ac01814192abf69023ae56b3 Mon Sep 17 00:00:00 2001 From: Pete Hodgson Date: Wed, 4 Dec 2024 00:13:07 -0800 Subject: [PATCH 262/335] Fix instrumentation of SQLAlchemy when using sqlalchemy.engine_from_config (#2816) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wrap sqlalchemy.engine.create.create_engine sqlalchemy.engine_from_config directly calls create_engine imported from that path; if we don't wrap that copy of the `create_engine` call then engines created via engine_from_config are not instrumented. * add changelog entry * Update CHANGELOG.md Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Update instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> * make some monkey-patching conditional on the version of SQLAlchemy * lint * fix changelog Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * Update CHANGELOG.md --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Leighton Chen Co-authored-by: Shalev Roda <65566801+shalevr@users.noreply.github.com> Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../instrumentation/sqlalchemy/__init__.py | 14 ++++++++++++++ .../tests/test_sqlalchemy.py | 11 +++++++++++ 3 files changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a1039f83a..33f83bb0ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022)) - Replace all instrumentor unit test `assertEqualSpanInstrumentationInfo` calls with `assertEqualSpanInstrumentationScope` calls ([#3037](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3037)) +- `opentelemetry-instrumentation-sqlalchemy` Fixes engines from `sqlalchemy.engine_from_config` not being fully instrumented + ([#2816](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2816)) - `opentelemetry-instrumentation-sqlalchemy`: Fix a remaining memory leak in EngineTracer ([#3053](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3053)) diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py index 9889e18b5a..4182c0034e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py @@ -181,6 +181,18 @@ def _instrument(self, **kwargs): tracer, connections_usage, enable_commenter, commenter_options ), ) + # sqlalchemy.engine.create is not present in earlier versions of sqlalchemy (which we support) + if parse_version(sqlalchemy.__version__).release >= (1, 4): + _w( + "sqlalchemy.engine.create", + "create_engine", + _wrap_create_engine( + tracer, + connections_usage, + enable_commenter, + commenter_options, + ), + ) _w( "sqlalchemy.engine.base", "Engine.connect", @@ -224,6 +236,8 @@ def _instrument(self, **kwargs): def _uninstrument(self, **kwargs): unwrap(sqlalchemy, "create_engine") unwrap(sqlalchemy.engine, "create_engine") + if parse_version(sqlalchemy.__version__).release >= (1, 4): + unwrap(sqlalchemy.engine.create, "create_engine") unwrap(Engine, "connect") if parse_version(sqlalchemy.__version__).release >= (1, 4): unwrap(sqlalchemy.ext.asyncio, "create_async_engine") diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py index 18b9fa65f7..27a253decb 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py @@ -182,6 +182,17 @@ def test_create_engine_wrapper(self): "opentelemetry.instrumentation.sqlalchemy", ) + def test_instrument_engine_from_config(self): + SQLAlchemyInstrumentor().instrument() + from sqlalchemy import engine_from_config # pylint: disable-all + + engine = engine_from_config({"sqlalchemy.url": "sqlite:///:memory:"}) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + self.assertEqual(len(spans), 2) + def test_create_engine_wrapper_enable_commenter(self): logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) SQLAlchemyInstrumentor().instrument( From 9cf26836bdc998823a10b9809d38a25d3b8c6bfc Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 4 Dec 2024 09:27:56 +0100 Subject: [PATCH 263/335] CONTRIBUTING: notes abount adding doc for new instrumentation (#3064) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * CONTRIBUTING: notes abount adding doc for new instrumentation While at it revise the versioning paragraph to take into account the openai instrumentation. * Reword doc paragraph * Update CONTRIBUTING.md Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Add autodoc template * Add notes about tox --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- CONTRIBUTING.md | 6 +++++- _template/autodoc_entry.rst | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 _template/autodoc_entry.rst diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 633a356c40..e90402edc2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -272,7 +272,11 @@ Below is a checklist of things to be mindful of when implementing a new instrume - Isolate sync and async test - For synchronous tests, the typical test case class is inherited from `opentelemetry.test.test_base.TestBase`. However, if you want to write asynchronous tests, the test case class should inherit also from `IsolatedAsyncioTestCase`. Adding asynchronous tests to a common test class can lead to tests passing without actually running, which can be misleading. - ex. -- All instrumentations have the same version. If you are going to develop a new instrumentation it would probably have `X.Y.dev` version and depends on `opentelemetry-instrumentation` and `opentelemetry-semantic-conventions` for the same version. That means that if you want to install your instrumentation you need to install its dependencies from this repo and the core repo also from git. +- Most of the instrumentations have the same version. If you are going to develop a new instrumentation it would probably have `X.Y.dev` version and depends on `opentelemetry-instrumentation` and `opentelemetry-semantic-conventions` for a [compatible version](https://peps.python.org/pep-0440/#compatible-release). That means that you may need to install the instrumentation dependencies from this repo and the core repo from git. +- Documentation + - When adding a new instrumentation remember to add an entry in `docs/instrumentation/` named `/.rst` to have the instrumentation documentation referenced from the index. You can use the entry template available [here](./_template/autodoc_entry.rst) +- Testing + - When adding a new instrumentation remember to update `tox.ini` adding appropriate rules in `envlist`, `command_pre` and `commands` sections ## Guideline for GenAI instrumentations diff --git a/_template/autodoc_entry.rst b/_template/autodoc_entry.rst new file mode 100644 index 0000000000..ee2688bacd --- /dev/null +++ b/_template/autodoc_entry.rst @@ -0,0 +1,7 @@ +.. include:: ../../../instrumentation/opentelemetry-instrumentation-/README.rst + :end-before: References + +.. automodule:: opentelemetry.instrumentation. + :members: + :undoc-members: + :show-inheritance: From f393546d4a03ad32f996de058f113405997fc4a7 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Wed, 4 Dec 2024 15:14:12 +0100 Subject: [PATCH 264/335] Add type hints to SQLite3 (#3057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add type hints to SQLite3 * Apply suggestions from code review * Update instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/package.py * This is a type alias, pylint is dumb --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Aaron Abbott --- .../instrumentation/sqlite3/__init__.py | 22 ++++++++++++++----- .../instrumentation/sqlite3/package.py | 4 ++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py index 9b3ae28a95..1ec4794e96 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py @@ -39,20 +39,27 @@ --- """ +from __future__ import annotations + import sqlite3 from sqlite3 import dbapi2 -from typing import Collection +from typing import Any, Collection, TypeVar, Union from opentelemetry.instrumentation import dbapi from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.sqlite3.package import _instruments from opentelemetry.instrumentation.sqlite3.version import __version__ +from opentelemetry.trace import TracerProvider # No useful attributes of sqlite3 connection object _CONNECTION_ATTRIBUTES = {} _DATABASE_SYSTEM = "sqlite" +SQLite3Connection = TypeVar( # pylint: disable=invalid-name + "SQLite3Connection", bound=Union[sqlite3.Connection, None] +) + class SQLite3Instrumentor(BaseInstrumentor): _TO_WRAP = [sqlite3, dbapi2] @@ -60,7 +67,7 @@ class SQLite3Instrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any) -> None: """Integrate with SQLite3 Python library. https://docs.python.org/3/library/sqlite3.html """ @@ -77,13 +84,16 @@ def _instrument(self, **kwargs): tracer_provider=tracer_provider, ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any) -> None: """ "Disable SQLite3 instrumentation""" for module in self._TO_WRAP: dbapi.unwrap_connect(module, "connect") @staticmethod - def instrument_connection(connection, tracer_provider=None): + def instrument_connection( + connection: SQLite3Connection, + tracer_provider: TracerProvider | None = None, + ) -> SQLite3Connection: """Enable instrumentation in a SQLite connection. Args: @@ -105,7 +115,9 @@ def instrument_connection(connection, tracer_provider=None): ) @staticmethod - def uninstrument_connection(connection): + def uninstrument_connection( + connection: SQLite3Connection, + ) -> SQLite3Connection: """Disable instrumentation in a SQLite connection. Args: diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/package.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/package.py index 7a66a17a93..0de6133b4a 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/package.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/package.py @@ -11,6 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations - -_instruments = tuple() +_instruments: tuple[str, ...] = tuple() From 6c92f387aa6f2ea606728077aad47791b0eb33b5 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Thu, 5 Dec 2024 15:53:21 +0300 Subject: [PATCH 265/335] Fix doc formatting issues (#3062) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../src/opentelemetry/instrumentation/aiokafka/__init__.py | 5 +++-- .../instrumentation/confluent_kafka/__init__.py | 4 +--- .../src/opentelemetry/instrumentation/kafka/__init__.py | 5 +++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py index 507206f4f2..4b14ace4fb 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/__init__.py @@ -18,7 +18,7 @@ Usage ----- -..code:: python +.. code:: python from opentelemetry.instrumentation.aiokafka import AIOKafkaInstrumentor from aiokafka import AIOKafkaProducer, AIOKafkaConsumer @@ -45,7 +45,8 @@ def async_produce_hook(span: Span, args, kwargs) def async_consume_hook(span: Span, record: kafka.record.ABCRecord, args, kwargs) for example: -.. code: python +.. code:: python + from opentelemetry.instrumentation.kafka import AIOKafkaInstrumentor from aiokafka import AIOKafkaProducer, AIOKafkaConsumer diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index aaf906d118..48b2bd2c26 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -18,7 +18,7 @@ Usage ----- -.. code-block:: python +.. code:: python from opentelemetry.instrumentation.confluent_kafka import ConfluentKafkaInstrumentor from confluent_kafka import Producer, Consumer @@ -54,7 +54,6 @@ def basic_consume_loop(consumer, topics): consumer.close() basic_consume_loop(consumer, "my-topic") - --- The _instrument method accepts the following keyword args: tracer_provider (TracerProvider) - an optional tracer provider @@ -95,7 +94,6 @@ def instrument_consumer(consumer: Consumer, tracer_provider=None) p.produce('my-topic',b'raw_bytes') msg = c.poll() -___ """ from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py index 9b0f4895f9..1e0dbf79e1 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/__init__.py @@ -18,7 +18,7 @@ Usage ----- -..code:: python +.. code:: python from opentelemetry.instrumentation.kafka import KafkaInstrumentor from kafka import KafkaProducer, KafkaConsumer @@ -45,7 +45,8 @@ def produce_hook(span: Span, args, kwargs) def consume_hook(span: Span, record: kafka.record.ABCRecord, args, kwargs) for example: -.. code: python +.. code:: python + from opentelemetry.instrumentation.kafka import KafkaInstrumentor from kafka import KafkaProducer, KafkaConsumer From 6134d5a2f969d832bd38a6ede6230c34d0e298a8 Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:46:13 +0800 Subject: [PATCH 266/335] opentelemetry-instrumentation-openai-v2: coerce openai response_format to semconv format (#3073) * opentelemetry-instrumentation-openai-v2: coerce openai response_format to semconv format Signed-off-by: Adrian Cole * changelog Signed-off-by: Adrian Cole --------- Signed-off-by: Adrian Cole --- .../CHANGELOG.md | 2 ++ .../instrumentation/openai_v2/utils.py | 19 ++++++++--- ...st_async_chat_completion_extra_params.yaml | 33 ++++++++++--------- .../test_chat_completion_extra_params.yaml | 33 ++++++++++--------- .../tests/test_async_chat_completions.py | 7 ++++ .../tests/test_chat_completions.py | 7 ++++ 6 files changed, 66 insertions(+), 35 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 2c10498511..4644ee3dc5 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Coerce openai response_format to semconv format + ([#3073](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3073)) - Add example to `opentelemetry-instrumentation-openai-v2` ([#3006](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3006)) - Support for `AsyncOpenAI/AsyncCompletions` ([#2984](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2984)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index cf920c17ee..f8a837259e 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -13,7 +13,7 @@ # limitations under the License. from os import environ -from typing import Optional, Union +from typing import Mapping, Optional, Union from urllib.parse import urlparse from httpx import URL @@ -202,12 +202,23 @@ def get_llm_request_attributes( GenAIAttributes.GEN_AI_REQUEST_FREQUENCY_PENALTY: kwargs.get( "frequency_penalty" ), - GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: kwargs.get( - "response_format" - ), GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED: kwargs.get("seed"), } + if (response_format := kwargs.get("response_format")) is not None: + # response_format may be string or object with a string in the `type` key + if isinstance(response_format, Mapping): + if ( + response_format_type := response_format.get("type") + ) is not None: + attributes[ + GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT + ] = response_format_type + else: + attributes[ + GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT + ] = response_format + set_server_address_and_port(client_instance, attributes) service_tier = kwargs.get("service_tier") attributes[GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER] = ( diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml index 3d13c9344e..37c18b091a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml @@ -10,6 +10,9 @@ interactions: ], "model": "gpt-4o-mini", "max_tokens": 50, + "response_format": { + "type": "text" + }, "seed": 42, "stream": false, "temperature": 0.5, @@ -25,7 +28,7 @@ interactions: connection: - keep-alive content-length: - - '183' + - '220' content-type: - application/json host: @@ -45,16 +48,16 @@ interactions: x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.5 + - 3.12.7 method: POST uri: https://api.openai.com/v1/chat/completions response: body: string: |- { - "id": "chatcmpl-ASv9WMTAMZY4O1EImv3csZa6Ch7KI", + "id": "chatcmpl-AbMH3rR6OBMN9hG5w0TRrezuiHLMr", "object": "chat.completion", - "created": 1731456242, + "created": 1733467121, "model": "gpt-4o-mini-2024-07-18", "choices": [ { @@ -84,19 +87,19 @@ interactions: } }, "service_tier": "default", - "system_fingerprint": "fp_0ba0d124f1" + "system_fingerprint": "fp_bba3c8e70b" } headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8e1a8088f867e167-MRS + - 8eda4640ead3e535-KUL Connection: - keep-alive Content-Type: - application/json Date: - - Wed, 13 Nov 2024 00:04:02 GMT + - Fri, 06 Dec 2024 06:38:42 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -112,25 +115,25 @@ interactions: - '825' openai-organization: test_openai_org_id openai-processing-ms: - - '488' + - '835' openai-version: - '2020-10-01' strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - '30000' + - '10000' x-ratelimit-limit-tokens: - - '150000000' + - '200000' x-ratelimit-remaining-requests: - - '29999' + - '9999' x-ratelimit-remaining-tokens: - - '149999943' + - '199943' x-ratelimit-reset-requests: - - 2ms + - 8.64s x-ratelimit-reset-tokens: - - 0s + - 16ms x-request-id: - - req_6df08d6267415e8f5db3628a6757edad + - req_fea877c0a861ff92a6a5217247681f24 status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml index 7cc89ad9b8..87f9673512 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml @@ -10,6 +10,9 @@ interactions: ], "model": "gpt-4o-mini", "max_tokens": 50, + "response_format": { + "type": "text" + }, "seed": 42, "stream": false, "temperature": 0.5, @@ -25,13 +28,13 @@ interactions: connection: - keep-alive content-length: - - '183' + - '220' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.54.3 + - OpenAI/Python 1.26.0 x-stainless-arch: - arm64 x-stainless-async: @@ -41,22 +44,20 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' + - 1.26.0 x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.6 + - 3.12.7 method: POST uri: https://api.openai.com/v1/chat/completions response: body: string: |- { - "id": "chatcmpl-ASYMT7913Sp58qhZqQgY7g7Ia2J4M", + "id": "chatcmpl-AbMH70fQA9lMPIClvBPyBSjqJBm9F", "object": "chat.completion", - "created": 1731368633, + "created": 1733467125, "model": "gpt-4o-mini-2024-07-18", "choices": [ { @@ -86,19 +87,17 @@ interactions: } }, "service_tier": "default", - "system_fingerprint": "fp_0ba0d124f1" + "system_fingerprint": "fp_0705bf87c0" } headers: - CF-Cache-Status: - - DYNAMIC CF-RAY: - - 8e1225a3f8e9ce65-SIN + - 8eda465e8fe9e58c-KUL Connection: - keep-alive Content-Type: - application/json Date: - - Mon, 11 Nov 2024 23:43:53 GMT + - Fri, 06 Dec 2024 06:38:46 GMT Server: - cloudflare Set-Cookie: test_set_cookie @@ -110,11 +109,13 @@ interactions: - X-Request-ID alt-svc: - h3=":443"; ma=86400 + cf-cache-status: + - DYNAMIC content-length: - '825' openai-organization: test_openai_org_id openai-processing-ms: - - '431' + - '558' openai-version: - '2020-10-01' strict-transport-security: @@ -128,11 +129,11 @@ interactions: x-ratelimit-remaining-tokens: - '199943' x-ratelimit-reset-requests: - - 14.746s + - 12.967s x-ratelimit-reset-tokens: - 16ms x-request-id: - - req_81e29a8992ea8001c0240bd990acf0ab + - req_22ff608d47a299f0780f52360631eabb status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py index e19bc7c311..65c596796d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py @@ -158,6 +158,7 @@ async def test_async_chat_completion_extra_params( max_tokens=50, stream=False, extra_body={"service_tier": "default"}, + response_format={"type": "text"}, ) spans = span_exporter.get_finished_spans() @@ -173,6 +174,12 @@ async def test_async_chat_completion_extra_params( spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] == "default" ) + assert ( + spans[0].attributes[ + GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT + ] + == "text" + ) @pytest.mark.vcr() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index 4f732290c0..4677b7cb95 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -151,6 +151,7 @@ def test_chat_completion_extra_params( max_tokens=50, stream=False, extra_body={"service_tier": "default"}, + response_format={"type": "text"}, ) spans = span_exporter.get_finished_spans() @@ -166,6 +167,12 @@ def test_chat_completion_extra_params( spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] == "default" ) + assert ( + spans[0].attributes[ + GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT + ] + == "text" + ) @pytest.mark.vcr() From eb394c0b210135c81b03b3de3830ce53b33dff32 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 9 Dec 2024 14:31:31 +0100 Subject: [PATCH 267/335] opentelemetry-instrumentation-tornado: bump tornado in test requirements (#3079) --- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 56a088ec62..2a16e05476 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -17,7 +17,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 requests==2.32.3 tomli==2.0.1 -tornado==6.4.1 +tornado==6.4.2 typing_extensions==4.12.2 urllib3==2.2.2 Werkzeug==3.0.3 From c530f0d98ff4846cafebb942757f0178a5a7baaa Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 9 Dec 2024 14:46:44 +0100 Subject: [PATCH 268/335] instrumentation: Bump Werkzeug to 3.0.6 (#3078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-pyramid/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 8a0c88f805..04f853bdbf 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -24,7 +24,7 @@ requests==2.32.3 tomli==2.0.1 typing_extensions==4.12.2 urllib3==2.2.2 -Werkzeug==3.0.3 +Werkzeug==3.0.6 wrapt==1.16.0 yarl==1.9.4 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt index 5253cf3bba..aa5f89859f 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt @@ -29,7 +29,7 @@ six==1.16.0 tomli==2.0.1 typing_extensions==4.12.2 urllib3==1.26.19 -Werkzeug==3.0.3 +Werkzeug==3.0.6 wrapt==1.16.0 xmltodict==0.13.0 zipp==3.19.2 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 59edf6f540..d7bf77e315 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -13,7 +13,7 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -Werkzeug==3.0.3 +Werkzeug==3.0.6 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 97815133f8..157b9b6040 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -15,7 +15,7 @@ translationstring==1.4 typing_extensions==4.12.2 venusian==3.1.0 WebOb==1.8.8 -Werkzeug==3.0.3 +Werkzeug==3.0.6 wrapt==1.16.0 zipp==3.19.2 zope.deprecation==5.0 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 2a16e05476..2df7df38ec 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -20,7 +20,7 @@ tomli==2.0.1 tornado==6.4.2 typing_extensions==4.12.2 urllib3==2.2.2 -Werkzeug==3.0.3 +Werkzeug==3.0.6 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation From ecf5529f99222e7d945eddcaa83acb8a47c9ba42 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 9 Dec 2024 18:08:17 +0100 Subject: [PATCH 269/335] opentelemetry-instrumentation-django: bump to 4.2.17 in test requirements (#3077) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 1ee4b0bfbf..6d84c3db89 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,7 +1,7 @@ asgiref==3.8.1 backports.zoneinfo==0.2.1 Deprecated==1.2.14 -Django==4.2.15 +Django==4.2.17 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index aba0b28fa2..61ed226da4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -1,6 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 -Django==4.2.15 +Django==4.2.17 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 From 7804e0a4e81f741607c9007226d0b39c697d7aea Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Wed, 11 Dec 2024 10:37:51 +0100 Subject: [PATCH 270/335] Add type hints to BaseInstrumentor (#3084) --- .../instrumentation/dependencies.py | 16 +++++++++------- .../instrumentation/instrumentor.py | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py index 7ebc88d647..8f0a383412 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations + from logging import getLogger -from typing import Collection, Optional, Union +from typing import Collection from packaging.requirements import InvalidRequirement, Requirement @@ -27,10 +29,10 @@ class DependencyConflict: - required: str = None - found: Optional[str] = None + required: str | None = None + found: str | None = None - def __init__(self, required, found=None): + def __init__(self, required: str | None, found: str | None = None): self.required = required self.found = found @@ -40,7 +42,7 @@ def __str__(self): def get_dist_dependency_conflicts( dist: Distribution, -) -> Optional[DependencyConflict]: +) -> DependencyConflict | None: instrumentation_deps = [] extra = "extra" instruments = "instruments" @@ -57,8 +59,8 @@ def get_dist_dependency_conflicts( def get_dependency_conflicts( - deps: Collection[Union[str, Requirement]], -) -> Optional[DependencyConflict]: + deps: Collection[str | Requirement], +) -> DependencyConflict | None: for dep in deps: if isinstance(dep, Requirement): req = dep diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py index c612bfeceb..cf079dbfb7 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py @@ -17,9 +17,11 @@ OpenTelemetry Base Instrumentor """ +from __future__ import annotations + from abc import ABC, abstractmethod from logging import getLogger -from typing import Collection, Optional +from typing import Any, Collection from opentelemetry.instrumentation._semconv import ( _OpenTelemetrySemanticConventionStability, @@ -33,7 +35,7 @@ class BaseInstrumentor(ABC): - """An ABC for instrumentors + """An ABC for instrumentors. Child classes of this ABC should instrument specific third party libraries or frameworks either by using the @@ -74,18 +76,18 @@ def instrumentation_dependencies(self) -> Collection[str]: is present in the environment. """ - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Instrument the library""" @abstractmethod - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): """Uninstrument the library""" - def _check_dependency_conflicts(self) -> Optional[DependencyConflict]: + def _check_dependency_conflicts(self) -> DependencyConflict | None: dependencies = self.instrumentation_dependencies() return get_dependency_conflicts(dependencies) - def instrument(self, **kwargs): + def instrument(self, **kwargs: Any): """Instrument the library This method will be called without any optional arguments by the @@ -117,7 +119,7 @@ def instrument(self, **kwargs): self._is_instrumented_by_opentelemetry = True return result - def uninstrument(self, **kwargs): + def uninstrument(self, **kwargs: Any): """Uninstrument the library See ``BaseInstrumentor.instrument`` for more information regarding the From e32aac7b1824703bad29ac6f358edacfbff06408 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Wed, 11 Dec 2024 12:25:01 +0100 Subject: [PATCH 271/335] Improve SQLite3 example (#3083) Co-authored-by: Riccardo Magliocchetti --- .../src/opentelemetry/instrumentation/sqlite3/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py index 1ec4794e96..58a6e291cf 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py @@ -29,8 +29,9 @@ SQLite3Instrumentor().instrument() - cnx = sqlite3.connect('example.db') + cnx = sqlite3.connect(':memory:') cursor = cnx.cursor() + cursor.execute("CREATE TABLE test (testField INTEGER)") cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() From 830231092d102b2c1ffb577bb6e7cff084be5b35 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Wed, 11 Dec 2024 03:59:21 -0800 Subject: [PATCH 272/335] Update sqlite3 instrumentor doc about explicit cursors (#3088) * Update sqlite3 instrumentor doc about explicit cursors * Changelog --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/sqlite3/__init__.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33f83bb0ae..d4938e9fcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2816](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2816)) - `opentelemetry-instrumentation-sqlalchemy`: Fix a remaining memory leak in EngineTracer ([#3053](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3053)) +- `opentelemetry-instrumentation-sqlite3`: Update documentation on explicit cursor support of tracing + ([#3088](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3088)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py index 58a6e291cf..ec4f8ecc50 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py @@ -14,7 +14,8 @@ """ SQLite instrumentation supporting `sqlite3`_, it can be enabled by -using ``SQLite3Instrumentor``. +using ``SQLite3Instrumentor``. At this time, cursor objects must +be explicitly initialized as shown below to support tracing. .. _sqlite3: https://docs.python.org/3/library/sqlite3.html From eb03dac1f0553bc7a2f0249013a7f88e4b3928a1 Mon Sep 17 00:00:00 2001 From: Diego Amaral Date: Wed, 11 Dec 2024 10:35:50 -0300 Subject: [PATCH 273/335] NoOpTracerProvider test case for botocore instrumentation (#3091) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../tests/test_botocore_instrumentation.py | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py index 62357a3336..fa8b497904 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py @@ -103,6 +103,19 @@ def test_traced_client(self): request_id = "fdcdcab1-ae5c-489e-9c33-4637c5dda355" self.assert_span("EC2", "DescribeInstances", request_id=request_id) + @mock_aws + def test_no_op_tracer_provider_ec2(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + ec2 = self._make_client("ec2") + ec2.describe_instances() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_not_recording(self): mock_tracer = Mock() @@ -148,6 +161,19 @@ def test_s3_client(self): s3.list_buckets() self.assert_span("S3", "ListBuckets") + @mock_aws + def test_no_op_tracer_provider_s3(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + s3 = self._make_client("s3") + s3.list_buckets() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_s3_put(self): s3 = self._make_client("s3") @@ -176,6 +202,19 @@ def test_sqs_client(self): "SQS", "ListQueues", request_id=_REQUEST_ID_REGEX_MATCH ) + @mock_aws + def test_no_op_tracer_provider_sqs(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + sqs = self._make_client("sqs") + sqs.list_queues() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_sqs_send_message(self): sqs = self._make_client("sqs") @@ -204,6 +243,19 @@ def test_kinesis_client(self): kinesis.list_streams() self.assert_span("Kinesis", "ListStreams") + @mock_aws + def test_no_op_tracer_provider_kinesis(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + kinesis = self._make_client("kinesis") + kinesis.list_streams() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_unpatch(self): kinesis = self._make_client("kinesis") @@ -213,6 +265,19 @@ def test_unpatch(self): kinesis.list_streams() self.assertEqual(0, len(self.memory_exporter.get_finished_spans())) + @mock_aws + def test_no_op_tracer_provider_kms(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + kms = self._make_client("kms") + kms.list_keys(Limit=21) + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_uninstrument_does_not_inject_headers(self): headers = {} @@ -268,6 +333,19 @@ def test_sts_client(self): # check for exact attribute set to make sure not to leak any sts secrets self.assertEqual(expected, dict(span.attributes)) + @mock_aws + def test_no_op_tracer_provider_sts(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + sts = self._make_client("sts") + sts.get_caller_identity() + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_propagator_injects_into_request(self): headers = {} @@ -308,6 +386,19 @@ def check_headers(**kwargs): finally: set_global_textmap(previous_propagator) + @mock_aws + def test_no_op_tracer_provider_xray(self): + BotocoreInstrumentor().uninstrument() + BotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + xray_client = self._make_client("xray") + xray_client.put_trace_segments(TraceSegmentDocuments=["str1"]) + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + @mock_aws def test_override_xray_propagator_injects_into_request(self): headers = {} From d2a51b95e54089a59fb36b3390aee1b6acf2b937 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Wed, 11 Dec 2024 16:02:37 +0100 Subject: [PATCH 274/335] docs: move `AwsLambdaInstrumentor().instrument()` to after the lambda function (#3085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../src/opentelemetry/instrumentation/aws_lambda/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index 68db87ca30..b31e6dea72 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -29,7 +29,6 @@ # Enable instrumentation BotocoreInstrumentor().instrument() - AwsLambdaInstrumentor().instrument() # Lambda function def lambda_handler(event, context): @@ -39,6 +38,8 @@ def lambda_handler(event, context): return "200 OK" + AwsLambdaInstrumentor().instrument() + API --- From 490580d6f3097fd6c2353fa7b022bbda2ee28e0a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 12 Dec 2024 05:17:53 -0600 Subject: [PATCH 275/335] Update version to 1.30.0.dev/0.51b0.dev (#3092) --- CHANGELOG.md | 2 + _template/version.py | 2 +- eachdist.ini | 4 +- .../prometheus_remote_write/version.py | 2 +- .../pyproject.toml | 2 +- .../exporter/richconsole/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/aio_pika/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_client/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_server/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiokafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiopg/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asgi/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncio/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncpg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aws_lambda/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto3sqs/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/botocore/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/cassandra/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/celery/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/click/version.py | 2 +- .../pyproject.toml | 2 +- .../confluent_kafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/dbapi/version.py | 2 +- .../pyproject.toml | 10 +- .../instrumentation/django/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/elasticsearch/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/falcon/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/fastapi/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/flask/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/grpc/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/httpx/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/jinja2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/kafka/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/logging/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysqlclient/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymemcache/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymongo/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymysql/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/pyramid/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/redis/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/remoulade/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/requests/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlalchemy/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlite3/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/starlette/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/system_metrics/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/threading/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/tornado/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/tortoiseorm/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib3/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/wsgi/version.py | 2 +- .../pyproject.toml | 98 ++++++++--------- .../contrib-instrumentations/version.py | 2 +- opentelemetry-distro/pyproject.toml | 4 +- .../src/opentelemetry/distro/version.py | 2 +- opentelemetry-instrumentation/pyproject.toml | 2 +- .../instrumentation/bootstrap_gen.py | 102 +++++++++--------- .../opentelemetry/instrumentation/version.py | 2 +- .../processor/baggage/version.py | 2 +- .../propagators/ot_trace/version.py | 2 +- .../resource/detector/container/version.py | 2 +- .../src/opentelemetry/util/http/version.py | 2 +- 115 files changed, 279 insertions(+), 277 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4938e9fcb..9b8d39ff0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 1.29.0/0.50b0 (2024-12-11) + ### Added - `opentelemetry-instrumentation-starlette` Add type hints to the instrumentation diff --git a/_template/version.py b/_template/version.py index 0559ba6227..6e2923f0db 100644 --- a/_template/version.py +++ b/_template/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/eachdist.ini b/eachdist.ini index e27258fe65..b63fa7edbc 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -16,7 +16,7 @@ sortfirst= ext/* [stable] -version=1.29.0.dev +version=1.30.0.dev packages= opentelemetry-sdk @@ -34,7 +34,7 @@ packages= opentelemetry-api [prerelease] -version=0.50b0.dev +version=0.51b0.dev packages= all diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py index 0559ba6227..6e2923f0db 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 03a38a8647..2d001c9f6e 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-sdk ~= 1.12", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "rich>=10.0.0", ] diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py index 0559ba6227..6e2923f0db 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index c6dff9b9bd..de0f7e6a71 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index f6f4263ec6..7fcb829bc6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py index 192d972f78..c683b00846 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 86df1fc38e..5e098e38b6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index 4398f686c8..a3fb3c15be 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.27", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 5236344665..13659d6a73 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index eef272575a..69378faf78 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ dependencies = [ "asgiref ~= 3.0", "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index b7e1287c72..b948a18067 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.14", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index b5ba5d6ad2..e4542789b9 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index bc5c7c4426..4ddc85072f 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index 68628c427a..c898e65dad 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -25,8 +25,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 172642033d..4341f2fab6 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 3e4618844f..f0e666d443 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 98b1121db4..79ba6ca83a 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 4c88789714..0355940416 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index d5b8e71830..f78c8ff605 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py +++ b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 5c9436513f..74be18efca 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "opentelemetry-api ~= 1.12", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index da1b043672..363f8e1cea 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py index d7d982fafc..c3c9026f93 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index 6b0204ef81..7a68a6206e 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -26,15 +26,15 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-wsgi == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-wsgi == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] asgi = [ - "opentelemetry-instrumentation-asgi == 0.50b0.dev", + "opentelemetry-instrumentation-asgi == 0.51b0.dev", ] instruments = [ "django >= 1.10", diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 32dcb1ad7e..051eb4d4a0 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index dd30ee6ba2..353020c014 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-wsgi == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-wsgi == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "packaging >= 20.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 9f64ab1ca4..ec5f3bedf4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-asgi == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-asgi == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index d5a27c78e7..f6ffbc8079 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-wsgi == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-wsgi == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "packaging >= 21.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index 18cb2d3f0e..b776422690 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index e4479223a4..255cea485a 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index 57f689a961..10fb75e60c 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index d5dc500101..e2249ce07c 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 2bb377f5ef..365539701e 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py index d7d982fafc..c3c9026f93 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 41273b0e22..1bfecd2183 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index 4edcbb08b1..4311f6b610 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 4c32c12e82..8fadfad325 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", "wrapt >= 1.0.0, < 2.0.0", diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 22af126330..363ae2807e 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index daf8c8efd4..0e30861d6f 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 0e1fa1a47f..f875c409d8 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index c9204d71b9..8a3a971790 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index fe68be60ab..c5f9b9955d 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 585a52c879..d7289f4e42 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-wsgi == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-wsgi == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index c46d97aa9a..00b44d2366 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.12.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index b7ff83f4db..97db24e18f 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index 7dab991cbc..a8a7792cc3 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index d6d8c7aff9..17c3095bf5 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "packaging >= 21.0", "wrapt >= 1.11.2", ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index d089fc27e9..40e5b140af 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-dbapi == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-dbapi == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py index d7d982fafc..c3c9026f93 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 13c4cc0fc2..4be53c57ab 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-instrumentation-asgi == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-instrumentation-asgi == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 3808b4ec0f..e8bc8375fd 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "opentelemetry-api ~= 1.11", "psutil >= 5.9.0, < 7", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 7f18ae7b40..5c0efc09aa 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index eaeb69324f..18104a99c4 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index f53e19018c..c83d9fbd5f 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index d7a98924aa..71ecc981c1 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index d7d982fafc..c3c9026f93 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index b1cf28d8ff..70a6183d99 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index dddb4a4eb1..ed9fd9bf24 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", - "opentelemetry-semantic-conventions == 0.50b0.dev", - "opentelemetry-util-http == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", + "opentelemetry-util-http == 0.51b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py index 0559ba6227..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index a0edde1390..36aec6a5c5 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -29,55 +29,55 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-instrumentation-aio-pika==0.50b0.dev", - "opentelemetry-instrumentation-aiohttp-client==0.50b0.dev", - "opentelemetry-instrumentation-aiohttp-server==0.50b0.dev", - "opentelemetry-instrumentation-aiokafka==0.50b0.dev", - "opentelemetry-instrumentation-aiopg==0.50b0.dev", - "opentelemetry-instrumentation-asgi==0.50b0.dev", - "opentelemetry-instrumentation-asyncio==0.50b0.dev", - "opentelemetry-instrumentation-asyncpg==0.50b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.50b0.dev", - "opentelemetry-instrumentation-boto==0.50b0.dev", - "opentelemetry-instrumentation-boto3sqs==0.50b0.dev", - "opentelemetry-instrumentation-botocore==0.50b0.dev", - "opentelemetry-instrumentation-cassandra==0.50b0.dev", - "opentelemetry-instrumentation-celery==0.50b0.dev", - "opentelemetry-instrumentation-click==0.50b0.dev", - "opentelemetry-instrumentation-confluent-kafka==0.50b0.dev", - "opentelemetry-instrumentation-dbapi==0.50b0.dev", - "opentelemetry-instrumentation-django==0.50b0.dev", - "opentelemetry-instrumentation-elasticsearch==0.50b0.dev", - "opentelemetry-instrumentation-falcon==0.50b0.dev", - "opentelemetry-instrumentation-fastapi==0.50b0.dev", - "opentelemetry-instrumentation-flask==0.50b0.dev", - "opentelemetry-instrumentation-grpc==0.50b0.dev", - "opentelemetry-instrumentation-httpx==0.50b0.dev", - "opentelemetry-instrumentation-jinja2==0.50b0.dev", - "opentelemetry-instrumentation-kafka-python==0.50b0.dev", - "opentelemetry-instrumentation-logging==0.50b0.dev", - "opentelemetry-instrumentation-mysql==0.50b0.dev", - "opentelemetry-instrumentation-mysqlclient==0.50b0.dev", - "opentelemetry-instrumentation-pika==0.50b0.dev", - "opentelemetry-instrumentation-psycopg==0.50b0.dev", - "opentelemetry-instrumentation-psycopg2==0.50b0.dev", - "opentelemetry-instrumentation-pymemcache==0.50b0.dev", - "opentelemetry-instrumentation-pymongo==0.50b0.dev", - "opentelemetry-instrumentation-pymysql==0.50b0.dev", - "opentelemetry-instrumentation-pyramid==0.50b0.dev", - "opentelemetry-instrumentation-redis==0.50b0.dev", - "opentelemetry-instrumentation-remoulade==0.50b0.dev", - "opentelemetry-instrumentation-requests==0.50b0.dev", - "opentelemetry-instrumentation-sqlalchemy==0.50b0.dev", - "opentelemetry-instrumentation-sqlite3==0.50b0.dev", - "opentelemetry-instrumentation-starlette==0.50b0.dev", - "opentelemetry-instrumentation-system-metrics==0.50b0.dev", - "opentelemetry-instrumentation-threading==0.50b0.dev", - "opentelemetry-instrumentation-tornado==0.50b0.dev", - "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", - "opentelemetry-instrumentation-urllib==0.50b0.dev", - "opentelemetry-instrumentation-urllib3==0.50b0.dev", - "opentelemetry-instrumentation-wsgi==0.50b0.dev", + "opentelemetry-instrumentation-aio-pika==0.51b0.dev", + "opentelemetry-instrumentation-aiohttp-client==0.51b0.dev", + "opentelemetry-instrumentation-aiohttp-server==0.51b0.dev", + "opentelemetry-instrumentation-aiokafka==0.51b0.dev", + "opentelemetry-instrumentation-aiopg==0.51b0.dev", + "opentelemetry-instrumentation-asgi==0.51b0.dev", + "opentelemetry-instrumentation-asyncio==0.51b0.dev", + "opentelemetry-instrumentation-asyncpg==0.51b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.51b0.dev", + "opentelemetry-instrumentation-boto==0.51b0.dev", + "opentelemetry-instrumentation-boto3sqs==0.51b0.dev", + "opentelemetry-instrumentation-botocore==0.51b0.dev", + "opentelemetry-instrumentation-cassandra==0.51b0.dev", + "opentelemetry-instrumentation-celery==0.51b0.dev", + "opentelemetry-instrumentation-click==0.51b0.dev", + "opentelemetry-instrumentation-confluent-kafka==0.51b0.dev", + "opentelemetry-instrumentation-dbapi==0.51b0.dev", + "opentelemetry-instrumentation-django==0.51b0.dev", + "opentelemetry-instrumentation-elasticsearch==0.51b0.dev", + "opentelemetry-instrumentation-falcon==0.51b0.dev", + "opentelemetry-instrumentation-fastapi==0.51b0.dev", + "opentelemetry-instrumentation-flask==0.51b0.dev", + "opentelemetry-instrumentation-grpc==0.51b0.dev", + "opentelemetry-instrumentation-httpx==0.51b0.dev", + "opentelemetry-instrumentation-jinja2==0.51b0.dev", + "opentelemetry-instrumentation-kafka-python==0.51b0.dev", + "opentelemetry-instrumentation-logging==0.51b0.dev", + "opentelemetry-instrumentation-mysql==0.51b0.dev", + "opentelemetry-instrumentation-mysqlclient==0.51b0.dev", + "opentelemetry-instrumentation-pika==0.51b0.dev", + "opentelemetry-instrumentation-psycopg==0.51b0.dev", + "opentelemetry-instrumentation-psycopg2==0.51b0.dev", + "opentelemetry-instrumentation-pymemcache==0.51b0.dev", + "opentelemetry-instrumentation-pymongo==0.51b0.dev", + "opentelemetry-instrumentation-pymysql==0.51b0.dev", + "opentelemetry-instrumentation-pyramid==0.51b0.dev", + "opentelemetry-instrumentation-redis==0.51b0.dev", + "opentelemetry-instrumentation-remoulade==0.51b0.dev", + "opentelemetry-instrumentation-requests==0.51b0.dev", + "opentelemetry-instrumentation-sqlalchemy==0.51b0.dev", + "opentelemetry-instrumentation-sqlite3==0.51b0.dev", + "opentelemetry-instrumentation-starlette==0.51b0.dev", + "opentelemetry-instrumentation-system-metrics==0.51b0.dev", + "opentelemetry-instrumentation-threading==0.51b0.dev", + "opentelemetry-instrumentation-tornado==0.51b0.dev", + "opentelemetry-instrumentation-tortoiseorm==0.51b0.dev", + "opentelemetry-instrumentation-urllib==0.51b0.dev", + "opentelemetry-instrumentation-urllib3==0.51b0.dev", + "opentelemetry-instrumentation-wsgi==0.51b0.dev", ] [project.urls] diff --git a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py index 0559ba6227..6e2923f0db 100644 --- a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py +++ b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index dd995f2f99..32c06ca723 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -27,13 +27,13 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.50b0.dev", + "opentelemetry-instrumentation == 0.51b0.dev", "opentelemetry-sdk ~= 1.13", ] [project.optional-dependencies] otlp = [ - "opentelemetry-exporter-otlp == 1.29.0.dev", + "opentelemetry-exporter-otlp == 1.30.0.dev", ] [project.entry-points.opentelemetry_configurator] diff --git a/opentelemetry-distro/src/opentelemetry/distro/version.py b/opentelemetry-distro/src/opentelemetry/distro/version.py index 0559ba6227..6e2923f0db 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/version.py +++ b/opentelemetry-distro/src/opentelemetry/distro/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index f8aad72f4a..616c22f7e9 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.4", - "opentelemetry-semantic-conventions == 0.50b0.dev", + "opentelemetry-semantic-conventions == 0.51b0.dev", "wrapt >= 1.0.0, < 2.0.0", "packaging >= 18.0", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index a292299d70..cffc612662 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -22,187 +22,187 @@ }, { "library": "aio_pika >= 7.2.0, < 10.0.0", - "instrumentation": "opentelemetry-instrumentation-aio-pika==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-aio-pika==0.51b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.51b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.51b0.dev", }, { "library": "aiokafka >= 0.8, < 1.0", - "instrumentation": "opentelemetry-instrumentation-aiokafka==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiokafka==0.51b0.dev", }, { "library": "aiopg >= 0.13.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiopg==0.51b0.dev", }, { "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-asgi==0.51b0.dev", }, { "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncpg==0.51b0.dev", }, { "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto==0.51b0.dev", }, { "library": "boto3 ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.51b0.dev", }, { "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.51b0.dev", }, { "library": "cassandra-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.51b0.dev", }, { "library": "scylla-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.51b0.dev", }, { "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-celery==0.51b0.dev", }, { "library": "click >= 8.1.3, < 9.0.0", - "instrumentation": "opentelemetry-instrumentation-click==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-click==0.51b0.dev", }, { "library": "confluent-kafka >= 1.8.2, <= 2.4.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.51b0.dev", }, { "library": "django >= 1.10", - "instrumentation": "opentelemetry-instrumentation-django==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-django==0.51b0.dev", }, { "library": "elasticsearch >= 6.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.51b0.dev", }, { "library": "falcon >= 1.4.1, < 3.1.2", - "instrumentation": "opentelemetry-instrumentation-falcon==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-falcon==0.51b0.dev", }, { "library": "fastapi ~= 0.58", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.51b0.dev", }, { "library": "flask >= 1.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-flask==0.51b0.dev", }, { "library": "grpcio >= 1.42.0", - "instrumentation": "opentelemetry-instrumentation-grpc==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-grpc==0.51b0.dev", }, { "library": "httpx >= 0.18.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-httpx==0.51b0.dev", }, { "library": "jinja2 >= 2.7, < 4.0", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-jinja2==0.51b0.dev", }, { "library": "kafka-python >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.51b0.dev", }, { "library": "kafka-python-ng >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.51b0.dev", }, { "library": "mysql-connector-python >= 8.0, < 10.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysql==0.51b0.dev", }, { "library": "mysqlclient < 3", - "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.51b0.dev", }, { "library": "pika >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-pika==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-pika==0.51b0.dev", }, { "library": "psycopg >= 3.1.0", - "instrumentation": "opentelemetry-instrumentation-psycopg==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg==0.51b0.dev", }, { "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.51b0.dev", }, { "library": "pymemcache >= 1.3.5, < 5", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymemcache==0.51b0.dev", }, { "library": "pymongo >= 3.1, < 5.0", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymongo==0.51b0.dev", }, { "library": "PyMySQL < 2", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymysql==0.51b0.dev", }, { "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-pyramid==0.51b0.dev", }, { "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-redis==0.51b0.dev", }, { "library": "remoulade >= 0.50", - "instrumentation": "opentelemetry-instrumentation-remoulade==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-remoulade==0.51b0.dev", }, { "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-requests==0.51b0.dev", }, { "library": "sqlalchemy >= 1.0.0, < 2.1.0", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.51b0.dev", }, { "library": "starlette ~= 0.13.0", - "instrumentation": "opentelemetry-instrumentation-starlette==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-starlette==0.51b0.dev", }, { "library": "psutil >= 5", - "instrumentation": "opentelemetry-instrumentation-system-metrics==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-system-metrics==0.51b0.dev", }, { "library": "tornado >= 5.1.1", - "instrumentation": "opentelemetry-instrumentation-tornado==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-tornado==0.51b0.dev", }, { "library": "tortoise-orm >= 0.17.0", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.51b0.dev", }, { "library": "pydantic >= 1.10.2", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.51b0.dev", }, { "library": "urllib3 >= 1.0.0, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.50b0.dev", + "instrumentation": "opentelemetry-instrumentation-urllib3==0.51b0.dev", }, ] default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.50b0.dev", - "opentelemetry-instrumentation-dbapi==0.50b0.dev", - "opentelemetry-instrumentation-logging==0.50b0.dev", - "opentelemetry-instrumentation-sqlite3==0.50b0.dev", - "opentelemetry-instrumentation-threading==0.50b0.dev", - "opentelemetry-instrumentation-urllib==0.50b0.dev", - "opentelemetry-instrumentation-wsgi==0.50b0.dev", + "opentelemetry-instrumentation-asyncio==0.51b0.dev", + "opentelemetry-instrumentation-dbapi==0.51b0.dev", + "opentelemetry-instrumentation-logging==0.51b0.dev", + "opentelemetry-instrumentation-sqlite3==0.51b0.dev", + "opentelemetry-instrumentation-threading==0.51b0.dev", + "opentelemetry-instrumentation-urllib==0.51b0.dev", + "opentelemetry-instrumentation-wsgi==0.51b0.dev", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index 0559ba6227..6e2923f0db 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py index 0559ba6227..6e2923f0db 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py index 0559ba6227..6e2923f0db 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py index 0559ba6227..6e2923f0db 100644 --- a/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py +++ b/resource/opentelemetry-resource-detector-container/src/opentelemetry/resource/detector/container/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py index 0559ba6227..6e2923f0db 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.50b0.dev" +__version__ = "0.51b0.dev" From 37e05aff8658be83279340ee8daeef4c6a8565d1 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 13 Dec 2024 14:53:17 +0100 Subject: [PATCH 276/335] Move starlette's py.typed to the right place (#3103) --- .../src/opentelemetry/instrumentation/{ => starlette}/py.typed | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/{ => starlette}/py.typed (100%) diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/py.typed b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/py.typed similarity index 100% rename from instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/py.typed rename to instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/py.typed From 38f0e33641142820aaa6cbcf71f33b45b188df5a Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 13 Dec 2024 16:39:07 +0100 Subject: [PATCH 277/335] opentelemetry-sdk-extension-aws: make eks detector less chatty (#3074) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * opentelemetry-sdk-extension-aws: make eks detector less chatty Don't print warnings if we are not running inside an eks instance so we can load the resource detector more generally and avoid warnings in stderr. * Update CHANGELOG --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .../CHANGELOG.md | 3 ++ .../sdk/extension/aws/resource/eks.py | 19 +++++++++--- .../tests/resource/test_eks.py | 31 ++++++++++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md index 2d01260554..a85ad43256 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md +++ b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Make EKS resource detector don't warn when not running in EKS + ([#3074](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3074)) + ## Version 2.0.2 (2024-08-05) See [common CHANGELOG](../../CHANGELOG.md) for the changes in this and prior versions. diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/eks.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/eks.py index c712e9875f..07f78b2d29 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/eks.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/eks.py @@ -14,6 +14,7 @@ import json import logging +import os import ssl from urllib.request import Request, urlopen @@ -29,6 +30,9 @@ _CONTAINER_ID_LENGTH = 64 _GET_METHOD = "GET" +_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token" +_CERT_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + def _aws_http_request(method, path, cred_value): with urlopen( @@ -39,7 +43,7 @@ def _aws_http_request(method, path, cred_value): ), timeout=5, context=ssl.create_default_context( - cafile="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + cafile=_CERT_PATH, ), ) as response: return response.read().decode("utf-8") @@ -47,10 +51,7 @@ def _aws_http_request(method, path, cred_value): def _get_k8s_cred_value(): try: - with open( - "/var/run/secrets/kubernetes.io/serviceaccount/token", - encoding="utf8", - ) as token_file: + with open(_TOKEN_PATH, encoding="utf8") as token_file: return "Bearer " + token_file.read() # pylint: disable=broad-except except Exception as exception: @@ -97,6 +98,10 @@ def _get_container_id(): return container_id +def _is_k8s() -> bool: + return os.path.exists(_TOKEN_PATH) and os.path.exists(_CERT_PATH) + + class AwsEksResourceDetector(ResourceDetector): """Detects attribute values only available when the app is running on AWS Elastic Kubernetes Service (EKS) and returns them in a Resource. @@ -106,6 +111,10 @@ class AwsEksResourceDetector(ResourceDetector): def detect(self) -> "Resource": try: + # if we are not running on eks exit early without warnings + if not _is_k8s(): + return Resource.get_empty() + cred_value = _get_k8s_cred_value() if not _is_eks(cred_value): diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py index a3819e6383..a2adcb3969 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_eks.py @@ -42,6 +42,10 @@ class AwsEksResourceDetectorTest(unittest.TestCase): "opentelemetry.sdk.extension.aws.resource.eks._is_eks", return_value=True, ) + @patch( + "opentelemetry.sdk.extension.aws.resource.eks._is_k8s", + return_value=True, + ) @patch( "opentelemetry.sdk.extension.aws.resource.eks._get_cluster_info", return_value=f"""{{ @@ -88,6 +92,7 @@ def test_simple_create( self, mock_open_function, mock_get_cluster_info, + mock_is_k8s, mock_is_eks, mock_get_k8_cred_value, ): @@ -104,8 +109,32 @@ def test_simple_create( "opentelemetry.sdk.extension.aws.resource.eks._is_eks", return_value=False, ) + @patch( + "opentelemetry.sdk.extension.aws.resource.eks._is_k8s", + return_value=True, + ) def test_if_no_eks_env_var_and_should_raise( - self, mock_is_eks, mock_get_k8_cred_value + self, mock_is_k8s, mock_is_eks, mock_get_k8_cred_value ): with self.assertRaises(RuntimeError): AwsEksResourceDetector(raise_on_error=True).detect() + + @patch( + "opentelemetry.sdk.extension.aws.resource.eks._get_k8s_cred_value", + return_value="MOCK_TOKEN", + ) + @patch( + "opentelemetry.sdk.extension.aws.resource.eks._is_eks", + return_value=False, + ) + @patch( + "opentelemetry.sdk.extension.aws.resource.eks._is_k8s", + return_value=False, + ) + def test_if_no_eks_paths_should_not_raise( + self, mock_is_k8s, mock_is_eks, mock_get_k8_cred_value + ): + try: + AwsEksResourceDetector(raise_on_error=True).detect() + except RuntimeError: + self.fail("Should not raise") From 770003dd174ea9ce3064a8185c0d611e055d173b Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 16 Dec 2024 11:28:18 +0100 Subject: [PATCH 278/335] opentelemetry-sdk-extension-aws: make ecs and beanstalk resource detector silent when loaded outside AWS (#3076) * opentelemetry-sdk-extension-aws: make ecs detector less chatty Don't print warnings if we are not running inside an ecs instance so we can load the resource detector more generally and avoid warnings in stderr. * opentelemetry-sdk-extension-aws: make beanstalk detector less chatty Don't print warnings if we are not running inside beanstalk so we can load the resource detector more generally and avoid warnings in stderr. * Add changelog --- .../opentelemetry-sdk-extension-aws/CHANGELOG.md | 2 ++ .../sdk/extension/aws/resource/beanstalk.py | 3 +++ .../opentelemetry/sdk/extension/aws/resource/ecs.py | 4 +--- .../tests/resource/test_beanstalk.py | 12 +++++++++++- .../tests/resource/test_ecs.py | 5 +++++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md index a85ad43256..c1c8286894 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md +++ b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Make ecs and beanstalk resource detector silent when loaded outside AWS + ([#3076](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3076)) - Make EKS resource detector don't warn when not running in EKS ([#3074](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3074)) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/beanstalk.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/beanstalk.py index 7d6fcd96ce..12e28bf35b 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/beanstalk.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/beanstalk.py @@ -41,6 +41,9 @@ def detect(self) -> "Resource": else: conf_file_path = "/var/elasticbeanstalk/xray/environment.conf" + if not os.path.exists(conf_file_path): + return Resource.get_empty() + try: with open(conf_file_path, encoding="utf-8") as conf_file: parsed_data = json.load(conf_file) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ecs.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ecs.py index b780633b69..07d4553350 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ecs.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ecs.py @@ -41,9 +41,7 @@ def detect(self) -> "Resource": if not os.environ.get( "ECS_CONTAINER_METADATA_URI" ) and not os.environ.get("ECS_CONTAINER_METADATA_URI_V4"): - raise RuntimeError( - "Missing ECS_CONTAINER_METADATA_URI therefore process is not on ECS." - ) + return Resource.get_empty() container_id = "" try: diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py index 29db8e459c..d41c0d9adb 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_beanstalk.py @@ -41,9 +41,19 @@ class AwsBeanstalkResourceDetectorTest(unittest.TestCase): new_callable=mock_open, read_data=f'{{"deployment_id":"{MockBeanstalkResourceAttributes[ResourceAttributes.SERVICE_INSTANCE_ID]}","environment_name":"{MockBeanstalkResourceAttributes[ResourceAttributes.SERVICE_NAMESPACE]}","version_label":"{MockBeanstalkResourceAttributes[ResourceAttributes.SERVICE_VERSION]}"}}', ) - def test_simple_create(self, mock_open_function): + @patch("os.path.exists", return_value=True) + def test_simple_create(self, mock_path_exists, mock_open_function): actual = AwsBeanstalkResourceDetector().detect() self.assertDictEqual( actual.attributes.copy(), OrderedDict(MockBeanstalkResourceAttributes), ) + + @patch("os.name", "posix") + @patch("os.path.exists", return_value=False) + def test_not_on_beanstalk(self, mock_path_exists): + actual = AwsBeanstalkResourceDetector().detect() + self.assertDictEqual(actual.attributes.copy(), {}) + mock_path_exists.assert_called_once_with( + "/var/elasticbeanstalk/xray/environment.conf" + ) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py index 4f892cc1bb..b116ae8229 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ecs.py @@ -79,6 +79,11 @@ def _http_get_function_fargate(url: str, *args, **kwargs) -> str: class AwsEcsResourceDetectorTest(unittest.TestCase): + @patch.dict("os.environ", {}, clear=True) + def test_not_on_ecs(self): + actual = AwsEcsResourceDetector().detect() + self.assertDictEqual(actual.attributes.copy(), {}) + @patch.dict( "os.environ", {"ECS_CONTAINER_METADATA_URI": "mock-uri"}, From 59ecd4d6080d11e0e4f28ac93051cf49c863f21c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:24:50 -0300 Subject: [PATCH 279/335] infra: improve tox for local development (#2999) * move pip install from command to deps Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * add docker-test-requirements.txt Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix celery and docs Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix tox.ini Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * update docs Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * Update tox.ini --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Leighton Chen --- dev-requirements.txt | 1 - .../tests/test-requirements.txt | 75 ++ tox.ini | 814 ++++++------------ 3 files changed, 354 insertions(+), 536 deletions(-) create mode 100644 tests/opentelemetry-docker-tests/tests/test-requirements.txt diff --git a/dev-requirements.txt b/dev-requirements.txt index 70464ffdd7..2668677cc5 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -8,7 +8,6 @@ pytest==7.4.4 pytest-cov==4.1.0 readme-renderer==42.0 bleach==4.1.0 # transient dependency for readme-renderer -protobuf~=3.13 markupsafe>=2.0.1 codespell==2.1.0 requests==2.32.3 diff --git a/tests/opentelemetry-docker-tests/tests/test-requirements.txt b/tests/opentelemetry-docker-tests/tests/test-requirements.txt new file mode 100644 index 0000000000..374aef7fff --- /dev/null +++ b/tests/opentelemetry-docker-tests/tests/test-requirements.txt @@ -0,0 +1,75 @@ +aiopg==1.4.0 +amqp==5.2.0 +asgiref==3.8.1 +async-timeout==4.0.3 +asyncpg==0.29.0 +attrs==23.2.0 +bcrypt==4.1.2 +billiard==4.2.0 +celery==5.3.6 +certifi==2024.2.2 +cffi==1.16.0 +chardet==3.0.4 +click==8.1.7 +click-didyoumean==0.3.0 +click-plugins==1.1.1 +click-repl==0.3.0 +cryptography==42.0.5 +Deprecated==1.2.14 +distro==1.9.0 +dnspython==2.6.1 +docker==5.0.3 +docker-compose==1.29.2 +dockerpty==0.4.1 +docopt==0.6.2 +exceptiongroup==1.2.0 +flaky==3.7.0 +greenlet==3.0.3 +grpcio==1.62.1 +idna==2.10 +iniconfig==2.0.0 +jsonschema==3.2.0 +kombu==5.3.5 +mysql-connector-python==8.3.0 +mysqlclient==2.1.1 +opencensus-proto==0.1.0 +packaging==24.0 +paramiko==3.4.0 +pluggy==1.4.0 +prometheus_client==0.20.0 +prompt-toolkit==3.0.43 +protobuf==3.20.3 +# prerequisite: install libpq-dev (debian) or postgresql-devel (rhel), postgresql (mac) +# see https://www.psycopg.org/docs/install.html#build-prerequisites +# you might have to install additional packages depending on your OS +psycopg==3.1.18 +psycopg2==2.9.9 +psycopg2-binary==2.9.9 +pycparser==2.21 +pymongo==4.6.3 +PyMySQL==0.10.1 +PyNaCl==1.5.0 +# prerequisite: install unixodbc +pyodbc==5.0.1 +pyrsistent==0.20.0 +pytest==8.0.2 +pytest-celery==0.0.0 +python-dateutil==2.9.0.post0 +python-dotenv==0.21.1 +pytz==2024.1 +PyYAML==5.3.1 +redis==5.0.1 +remoulade==3.2.0 +requests==2.25.0 +six==1.16.0 +SQLAlchemy==1.4.52 +texttable==1.7.0 +tomli==2.0.1 +typing_extensions==4.12.2 +tzdata==2024.1 +urllib3==1.26.19 +vine==5.1.0 +wcwidth==0.2.13 +websocket-client==0.59.0 +wrapt==1.16.0 +zipp==3.18.0 diff --git a/tox.ini b/tox.ini index 5fa58e5139..563f6cc34d 100644 --- a/tox.ini +++ b/tox.ini @@ -393,456 +393,281 @@ envlist = ruff [testenv] +test_deps = + opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api + opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions + opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk + opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + deps = lint: -r dev-requirements.txt coverage: pytest coverage: pytest-cov - ; FIXME: add coverage testing - ; FIXME: add mypy testing -allowlist_externals = - sh + opentelemetry-instrumentation: {[testenv]test_deps} + opentelemetry-instrumentation: -r {toxinidir}/opentelemetry-instrumentation/test-requirements.txt -setenv = - ; override CORE_REPO_SHA via env variable when testing other branches/commits than main - ; i.e: CORE_REPO_SHA=dde62cebffe519c35875af6d06fae053b3be65ec tox -e - CORE_REPO_SHA={env:CORE_REPO_SHA:main} - CORE_REPO=git+https://github.com/open-telemetry/opentelemetry-python.git@{env:CORE_REPO_SHA} - -commands_pre = - opentelemetry-instrumentation: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - opentelemetry-instrumentation: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - opentelemetry-instrumentation: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - opentelemetry-instrumentation: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - opentelemetry-instrumentation: pip install -r {toxinidir}/opentelemetry-instrumentation/test-requirements.txt + distro: {[testenv]test_deps} + distro: -r {toxinidir}/opentelemetry-distro/test-requirements.txt # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API # and SDK supported to test we are honoring it - openai-0: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt + openai-0: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt # and the latest version of OTel API and SDK - openai-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - openai-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - openai-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - openai-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - openai-1: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt - lint-instrumentation-openai-v2: pip install -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt - - distro: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - distro: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - distro: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - distro: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - distro: pip install -r {toxinidir}/opentelemetry-distro/test-requirements.txt - - asgi: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - asgi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - asgi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - asgi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - asgi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt - - celery: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - celery: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - celery: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - celery: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - py3{8,9}-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt - py3{10,11,12}-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt - pypy3-test-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt - lint-instrumentation-celery: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt - - click: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - click: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - click: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - click: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - click: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt - - sio-pika: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - sio-pika: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - sio-pika: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - sio-pika-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt - sio-pika-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt - lint-instrumentation-sio-pika: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt - - aio-pika: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - aio-pika: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - aio-pika: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - aio-pika-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt - aio-pika-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt - aio-pika-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt - aio-pika-3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt - lint-instrumentation-aio-pika: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt - - aiokafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - aiokafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - aiokafka: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - aiokafka: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - aiokafka: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt - - kafka-python: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - kafka-python: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - kafka-python: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - kafka-python: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt - kafka-pythonng: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - kafka-pythonng: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - kafka-pythonng: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - kafka-pythonng: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt - - confluent-kafka: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - confluent-kafka: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - confluent-kafka: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - confluent-kafka: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - confluent-kafka: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt - - grpc: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - grpc: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - grpc: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - grpc: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - grpc-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt - grpc-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt - lint-instrumentation-grpc: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt - - wsgi: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - wsgi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - wsgi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - wsgi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - wsgi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt - - asyncpg: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - asyncpg: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - asyncpg: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - asyncpg: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - asyncpg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt - - aws-lambda: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - aws-lambda: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - aws-lambda: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - aws-lambda: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - aws-lambda: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt - - boto: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - boto: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - boto: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - boto: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - boto: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt - - boto3sqs: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - boto3sqs: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - boto3sqs: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - boto3sqs: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - boto3sqs: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt - - falcon: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - falcon: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - falcon: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - falcon: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - falcon-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt - falcon-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt - falcon-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt - lint-instrumentation-falcon: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt - - flask: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - flask: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - flask: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - flask: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - flask-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt - flask-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt - flask-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt - lint-instrumentation-flask: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt - - urllib: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - urllib: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - urllib: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - urllib: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - urllib: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt - - urllib3: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - urllib3: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - urllib3: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - urllib3: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - urllib3-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt - urllib3-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt - lint-instrumentation-urllib3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt - - botocore: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - botocore: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - botocore: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - botocore: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - botocore: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt - - cassandra: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - cassandra: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - cassandra: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - cassandra: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - cassandra: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt - - dbapi: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - dbapi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - dbapi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - dbapi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - dbapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt - - django: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - django: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - django: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - django: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - py3{8,9}-test-instrumentation-django-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt - py3{8,9}-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{8,9}-test-instrumentation-django-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt - py3{10,11,12}-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{10,11,12}-test-instrumentation-django-3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt - pypy3-test-instrumentation-django-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt - pypy3-test-instrumentation-django-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - lint-instrumentation-django: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt - - fastapi: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - fastapi: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - fastapi: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - fastapi: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - fastapi: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt - - mysql: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - mysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - mysql: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - mysql: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - mysql-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt - mysql-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt - lint-instrumentation-mysql: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt - - mysqlclient: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - mysqlclient: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - mysqlclient: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - mysqlclient: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - mysqlclient: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt - - pymemcache: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - pymemcache: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - pymemcache: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - pymemcache: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - pymemcache-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt - pymemcache-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt - pymemcache-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt - pymemcache-3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt - pymemcache-4: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt - lint-instrumentation-pymemcache: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt - - pymongo: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - pymongo: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - pymongo: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - pymongo: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - pymongo: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt - - psycopg: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - psycopg: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - psycopg: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - psycopg: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - py3{8,9}-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt - py3{10,11,12}-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt - pypy3-test-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt - lint-instrumentation-psycopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt - - psycopg2: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - psycopg2: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - psycopg2: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - psycopg2: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - psycopg2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt - - pymysql: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - pymysql: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - pymysql: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - pymysql: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - pymysql: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt - - pyramid: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - pyramid: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - pyramid: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - pyramid: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - pyramid: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt - - sqlite3: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - sqlite3: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - sqlite3: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - sqlite3: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - sqlite3: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt - - redis: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - redis: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - redis: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - redis: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - redis: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt - - remoulade: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - remoulade: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - remoulade: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - remoulade: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - remoulade: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt - - requests: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - requests: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - requests: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - requests: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - requests: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt - - starlette: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - starlette: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - starlette: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - starlette: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - starlette: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt - - system-metrics: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - system-metrics: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - system-metrics: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - system-metrics: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - system-metrics: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt - - threading: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - threading: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - threading: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - threading: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - threading: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt - - tornado: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - tornado: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - tornado: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - tornado: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - tornado: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt - - tortoiseorm: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - tortoiseorm: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - tortoiseorm: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - tortoiseorm: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - tortoiseorm: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt - - jinja2: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - jinja2: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - jinja2: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - jinja2: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - jinja2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt - - logging: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - logging: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - logging: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - logging: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - logging: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt - - aiohttp-client: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - aiohttp-client: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - aiohttp-client: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - aiohttp-client: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - aiohttp-client: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt - - aiohttp-server: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - aiohttp-server: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - aiohttp-server: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - aiohttp-server: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - aiohttp-server: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt - - aiopg: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - aiopg: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - aiopg: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - aiopg: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - aiopg: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt - - richconsole: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - richconsole: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - richconsole: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - richconsole: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - richconsole: pip install -r {toxinidir}/exporter/opentelemetry-exporter-richconsole/test-requirements.txt - - prometheus: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - prometheus: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - prometheus: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - prometheus: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - prometheus: pip install -r {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt - - sqlalchemy: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - sqlalchemy: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - sqlalchemy: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - sqlalchemy: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - sqlalchemy-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt - sqlalchemy-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt - sqlalchemy-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt - lint-instrumentation-sqlalchemy: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt - - elasticsearch: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - elasticsearch: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - elasticsearch: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - elasticsearch: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - elasticsearch-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt - elasticsearch-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt - elasticsearch-2: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt - lint-instrumentation-elasticsearch: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt - - asyncio: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - asyncio: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - asyncio: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - asyncio: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - asyncio: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt - - httpx: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - httpx: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - httpx: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - httpx: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - httpx-0: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt - httpx-1: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt - lint-instrumentation-httpx: pip install -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt + openai-1: {[testenv]test_deps} + openai-1: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt + lint-instrumentation-openai-v2: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt + + asgi: {[testenv]test_deps} + asgi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt + + celery: {[testenv]test_deps} + py3{8,9}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt + py3{10,11,12}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt + pypy3-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt + lint-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt + + click: {[testenv]test_deps} + click: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt + + sio-pika: {[testenv]test_deps} + sio-pika-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt + sio-pika-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt + lint-instrumentation-sio-pika: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt + + aio-pika: {[testenv]test_deps} + aio-pika-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt + aio-pika-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt + aio-pika-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt + aio-pika-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt + lint-instrumentation-aio-pika: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt + + aiokafka: {[testenv]test_deps} + aiokafka: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt + + kafka-python: {[testenv]test_deps} + kafka-python: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt + + kafka-pythonng: {[testenv]test_deps} + kafka-pythonng: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt + + confluent-kafka: {[testenv]test_deps} + confluent-kafka: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt + + grpc: {[testenv]test_deps} + grpc-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt + grpc-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt + lint-instrumentation-grpc: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt + + wsgi: {[testenv]test_deps} + wsgi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt + + asyncpg: {[testenv]test_deps} + asyncpg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt + + aws-lambda: {[testenv]test_deps} + aws-lambda: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt + + boto: {[testenv]test_deps} + boto: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt + + boto3sqs: {[testenv]test_deps} + boto3sqs: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt + + falcon: {[testenv]test_deps} + falcon-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt + falcon-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt + falcon-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt + lint-instrumentation-falcon: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt + + flask: {[testenv]test_deps} + flask-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt + flask-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt + flask-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt + lint-instrumentation-flask: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt + + urllib: {[testenv]test_deps} + urllib: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt + + urllib3: {[testenv]test_deps} + urllib3-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt + urllib3-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt + lint-instrumentation-urllib3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt + + botocore: {[testenv]test_deps} + botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt + + cassandra: {[testenv]test_deps} + cassandra: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt + + dbapi: {[testenv]test_deps} + dbapi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt + + django: {[testenv]test_deps} + py3{8,9}-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt + py3{8,9}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + py3{8,9}-test-instrumentation-django-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt + py3{10,11,12}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + py3{10,11,12}-test-instrumentation-django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt + pypy3-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt + pypy3-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + lint-instrumentation-django: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt + + fastapi: {[testenv]test_deps} + fastapi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt + + mysql: {[testenv]test_deps} + mysql-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt + mysql-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt + lint-instrumentation-mysql: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt + + mysqlclient: {[testenv]test_deps} + mysqlclient: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt + + pymemcache: {[testenv]test_deps} + pymemcache-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt + pymemcache-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt + pymemcache-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt + pymemcache-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt + pymemcache-4: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt + lint-instrumentation-pymemcache: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt + + pymongo: {[testenv]test_deps} + pymongo: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt + + psycopg: {[testenv]test_deps} + py3{8,9}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt + py3{10,11,12}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt + pypy3-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt + lint-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt + + psycopg2: {[testenv]test_deps} + psycopg2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt + + pymysql: {[testenv]test_deps} + pymysql: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt + + pyramid: {[testenv]test_deps} + pyramid: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt + + sqlite3: {[testenv]test_deps} + sqlite3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt + + redis: {[testenv]test_deps} + redis: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt + + remoulade: {[testenv]test_deps} + remoulade: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt + + requests: {[testenv]test_deps} + requests: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt + + starlette: {[testenv]test_deps} + starlette: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.txt + + system-metrics: {[testenv]test_deps} + system-metrics: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt + + threading: {[testenv]test_deps} + threading: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt + + tornado: {[testenv]test_deps} + tornado: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt + + tortoiseorm: {[testenv]test_deps} + tortoiseorm: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt + + jinja2: {[testenv]test_deps} + jinja2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt + + logging: {[testenv]test_deps} + logging: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt + + aiohttp-client: {[testenv]test_deps} + aiohttp-client: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt + + aiohttp-server: {[testenv]test_deps} + aiohttp-server: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt + + aiopg: {[testenv]test_deps} + aiopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt + + richconsole: {[testenv]test_deps} + richconsole: -r {toxinidir}/exporter/opentelemetry-exporter-richconsole/test-requirements.txt + + prometheus: {[testenv]test_deps} + prometheus: -r {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt + + sqlalchemy: {[testenv]test_deps} + sqlalchemy-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt + sqlalchemy-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt + sqlalchemy-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt + lint-instrumentation-sqlalchemy: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt + + elasticsearch: {[testenv]test_deps} + elasticsearch-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt + elasticsearch-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt + elasticsearch-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt + lint-instrumentation-elasticsearch: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt + + asyncio: {[testenv]test_deps} + asyncio: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt + + httpx: {[testenv]test_deps} + httpx-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt + httpx-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt + lint-instrumentation-httpx: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API # and SDK supported to test we are honoring it - sdk-extension-aws-0: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt + sdk-extension-aws-0: -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt # and the latest version of OTel API and SDK - sdk-extension-aws-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - sdk-extension-aws-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - sdk-extension-aws-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - sdk-extension-aws-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - sdk-extension-aws-1: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt - lint-sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt - benchmark-sdk-extension-aws: pip install -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt - - resource-detector-container: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - resource-detector-container: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - resource-detector-container: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - resource-detector-container: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - resource-detector-container: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-container/test-requirements.txt + sdk-extension-aws-1: {[testenv]test_deps} + sdk-extension-aws-1: -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt + lint-sdk-extension-aws: -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt + benchmark-sdk-extension-aws: -r {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws/benchmark-requirements.txt + + resource-detector-container: {[testenv]test_deps} + resource-detector-container: -r {toxinidir}/resource/opentelemetry-resource-detector-container/test-requirements.txt # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API # and SDK supported to test we are honoring it - resource-detector-azure-0: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt + resource-detector-azure-0: -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt # and the latest version of OTel API and SDK - resource-detector-azure-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - resource-detector-azure-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - resource-detector-azure-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - resource-detector-azure-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - resource-detector-azure-1: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt - lint-resource-detector-azure: pip install -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt - - propagator-ot-trace: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - propagator-ot-trace: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - propagator-ot-trace: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - propagator-ot-trace: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - propagator-ot-trace: pip install -r {toxinidir}/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt + resource-detector-azure-1: {[testenv]test_deps} + resource-detector-azure-1: -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt + lint-resource-detector-azure: -r {toxinidir}/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt + + propagator-ot-trace: {[testenv]test_deps} + propagator-ot-trace: -r {toxinidir}/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API # and SDK supported to test we are honoring it - propagator-aws-xray-0: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt + propagator-aws-xray-0: -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt # and the latest version of OTel API and SDK - propagator-aws-xray-1: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - propagator-aws-xray-1: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - propagator-aws-xray-1: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - propagator-aws-xray-1: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - propagator-aws-xray-1: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt - lint-propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt - benchmark-propagator-aws-xray: pip install -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt - - processor-baggage: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - processor-baggage: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - processor-baggage: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - processor-baggage: pip install -r {toxinidir}/processor/opentelemetry-processor-baggage/test-requirements.txt - - util-http: pip install opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - util-http: pip install opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - util-http: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - util-http: pip install opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils - util-http: pip install -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt - util-http: pip install {toxinidir}/util/opentelemetry-util-http + propagator-aws-xray-1: {[testenv]test_deps} + propagator-aws-xray-1: -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt + lint-propagator-aws-xray: -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt + benchmark-propagator-aws-xray: -r {toxinidir}/propagator/opentelemetry-propagator-aws-xray/benchmark-requirements.txt + processor-baggage: {[testenv]test_deps} + processor-baggage: -r {toxinidir}/processor/opentelemetry-processor-baggage/test-requirements.txt + + util-http: {[testenv]test_deps} + util-http: -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt + util-http: {toxinidir}/util/opentelemetry-util-http + ; FIXME: add coverage testing + ; FIXME: add mypy testing +allowlist_externals = + sh + +setenv = + ; override CORE_REPO_SHA via env variable when testing other branches/commits than main + ; i.e: CORE_REPO_SHA=dde62cebffe519c35875af6d06fae053b3be65ec tox -e + CORE_REPO_SHA={env:CORE_REPO_SHA:main} + CORE_REPO=git+https://github.com/open-telemetry/opentelemetry-python.git@{env:CORE_REPO_SHA} + +commands_pre = ; In order to get a health coverage report, ; we have to install packages in editable mode. coverage: python {toxinidir}/scripts/eachdist.py install --editable @@ -1043,13 +868,9 @@ deps = -c {toxinidir}/dev-requirements.txt -r {toxinidir}/docs-requirements.txt pytest - -commands_pre = - python -m pip install {env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - python -m pip install {env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - python -m pip install {env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - python -m pip install {toxinidir}/opentelemetry-instrumentation - python -m pip install {toxinidir}/util/opentelemetry-util-http + {[testenv]test_deps} + {toxinidir}/opentelemetry-instrumentation + {toxinidir}/util/opentelemetry-util-http changedir = docs @@ -1068,81 +889,27 @@ commands = [testenv:docker-tests] basepython: python3 deps = - aiopg==1.4.0 - amqp==5.2.0 - asgiref==3.8.1 - async-timeout==4.0.3 - asyncpg==0.29.0 - attrs==23.2.0 - bcrypt==4.1.2 - billiard==4.2.0 - celery==5.3.6 - certifi==2024.2.2 - cffi==1.16.0 - chardet==3.0.4 - click==8.1.7 - click-didyoumean==0.3.0 - click-plugins==1.1.1 - click-repl==0.3.0 - cryptography==42.0.5 - Deprecated==1.2.14 - distro==1.9.0 - dnspython==2.6.1 - docker==5.0.3 - docker-compose==1.29.2 - dockerpty==0.4.1 - docopt==0.6.2 - exceptiongroup==1.2.0 - flaky==3.7.0 - greenlet==3.0.3 - grpcio==1.62.1 - idna==2.10 - iniconfig==2.0.0 - jsonschema==3.2.0 - kombu==5.3.5 - mysql-connector-python==8.3.0 - mysqlclient==2.1.1 - opencensus-proto==0.1.0 - packaging==24.0 - paramiko==3.4.0 - pluggy==1.4.0 - prometheus_client==0.20.0 - prompt-toolkit==3.0.43 - protobuf==3.20.3 - # prerequisite: install libpq-dev (debian) or postgresql-devel (rhel), postgresql (mac) - # see https://www.psycopg.org/docs/install.html#build-prerequisites - # you might have to install additional packages depending on your OS - psycopg==3.1.18 - psycopg2==2.9.9 - psycopg2-binary==2.9.9 - pycparser==2.21 - pymongo==4.6.3 - PyMySQL==0.10.1 - PyNaCl==1.5.0 - # prerequisite: install unixodbc - pyodbc==5.0.1 - pyrsistent==0.20.0 - pytest==8.0.2 - pytest-celery==0.0.0 - python-dateutil==2.9.0.post0 - python-dotenv==0.21.1 - pytz==2024.1 - PyYAML==5.3.1 - redis==5.0.1 - remoulade==3.2.0 - requests==2.25.0 - six==1.16.0 - SQLAlchemy==1.4.52 - texttable==1.7.0 - tomli==2.0.1 - typing_extensions==4.12.2 - tzdata==2024.1 - urllib3==1.26.19 - vine==5.1.0 - wcwidth==0.2.13 - websocket-client==0.59.0 - wrapt==1.16.0 - zipp==3.18.0 + {[testenv]test_deps} + -r {toxinidir}/tests/opentelemetry-docker-tests/tests/test-requirements.txt + -e {toxinidir}/opentelemetry-instrumentation + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-celery + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pika + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-redis + -e {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade + opentelemetry-exporter-opencensus@{env:CORE_REPO}\#egg=opentelemetry-exporter-opencensus&subdirectory=exporter/opentelemetry-exporter-opencensus changedir = tests/opentelemetry-docker-tests/tests @@ -1150,29 +917,6 @@ changedir = commands_pre = sh -c "sudo apt update -y && sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev unixodbc" python -c "import pyodbc; print(pyodbc.drivers())" - pip install {env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api \ - {env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions \ - {env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk \ - {env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils \ - -e {toxinidir}/opentelemetry-instrumentation \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-celery \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pika \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-mysqlclient \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2 \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-redis \ - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade \ - {env:CORE_REPO}\#egg=opentelemetry-exporter-opencensus&subdirectory=exporter/opentelemetry-exporter-opencensus docker-compose up -d python check_availability.py @@ -1197,9 +941,9 @@ commands = {toxinidir}/scripts/generate_instrumentation_metapackage.py [testenv:generate-workflows] - -commands_pre = - pip install {toxinidir}/.github/workflows/generate_workflows_lib +recreate = True +deps = + {toxinidir}/.github/workflows/generate_workflows_lib commands = python {toxinidir}/.github/workflows/generate_workflows.py From f8b0f726ce7de8ad390542b05f603fddd05dcdbd Mon Sep 17 00:00:00 2001 From: Adrian Cole <64215+codefromthecrypt@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:23:08 +0800 Subject: [PATCH 280/335] opentelemetry-instrumentation-openai-v2: updates versions in examples (#3102) --- .../examples/manual/requirements.txt | 6 +++--- .../examples/zero-code/requirements.txt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt index 436f63e1d5..75b6bee8f7 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt @@ -1,5 +1,5 @@ -openai~=1.54.4 +openai~=1.57.3 -opentelemetry-sdk~=1.28.2 -opentelemetry-exporter-otlp-proto-grpc~=1.28.2 +opentelemetry-sdk~=1.29.0 +opentelemetry-exporter-otlp-proto-grpc~=1.29.0 opentelemetry-instrumentation-openai-v2~=2.0b0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt index 77ed112ebb..df462da758 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt @@ -1,6 +1,6 @@ -openai~=1.54.4 +openai~=1.57.3 -opentelemetry-sdk~=1.28.2 -opentelemetry-exporter-otlp-proto-grpc~=1.28.2 -opentelemetry-distro~=0.49b2 +opentelemetry-sdk~=1.29.0 +opentelemetry-exporter-otlp-proto-grpc~=1.29.0 +opentelemetry-distro~=0.50b0 opentelemetry-instrumentation-openai-v2~=2.0b0 From d155540038068ee58c0f56b0a075208614acac0c Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 17 Dec 2024 18:43:22 +0100 Subject: [PATCH 281/335] httpx: update type hints to `RequestInfo`/`ResponseInfo` (#3105) --- CHANGELOG.md | 5 +++++ docs/nitpick-exceptions.ini | 2 ++ .../src/opentelemetry/instrumentation/httpx/__init__.py | 8 +++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b8d39ff0e..106d9408c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints + ([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105)) + ## Version 1.29.0/0.50b0 (2024-12-11) ### Added diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index 4b1b06f95b..e27bee26bb 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -29,6 +29,8 @@ py-class= httpx.SyncByteStream httpx.AsyncByteStream httpx.Response + httpx.URL + httpx.Headers aiohttp.web_request.Request yarl.URL cimpl.Producer diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 195c784408..d4e7571f61 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -192,6 +192,8 @@ async def async_response_hook(span, request, response): --- """ +from __future__ import annotations + import logging import typing from asyncio import iscoroutinefunction @@ -249,8 +251,8 @@ async def async_response_hook(span, request, response): class RequestInfo(typing.NamedTuple): method: bytes - url: URL - headers: typing.Optional[Headers] + url: httpx.URL + headers: httpx.Headers | None stream: typing.Optional[ typing.Union[httpx.SyncByteStream, httpx.AsyncByteStream] ] @@ -259,7 +261,7 @@ class RequestInfo(typing.NamedTuple): class ResponseInfo(typing.NamedTuple): status_code: int - headers: typing.Optional[Headers] + headers: httpx.Headers | None stream: typing.Iterable[bytes] extensions: typing.Optional[dict] From cc62d1f05e8b3acfaa97b86c4d483c29c0044587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:58:04 -0300 Subject: [PATCH 282/335] prepare semconv utilities to support database stability opt-in (#3111) --- CHANGELOG.md | 6 + .../aiohttp_client/__init__.py | 8 +- .../tests/test_aiohttp_client_integration.py | 16 +- .../instrumentation/asgi/__init__.py | 16 +- .../tests/test_asgi_middleware.py | 14 +- .../django/middleware/otel_middleware.py | 12 +- .../instrumentation/fastapi/__init__.py | 4 +- .../instrumentation/flask/__init__.py | 12 +- .../instrumentation/httpx/__init__.py | 6 +- .../instrumentation/requests/__init__.py | 8 +- .../instrumentation/urllib/__init__.py | 14 +- .../instrumentation/urllib3/__init__.py | 16 +- .../tests/test_urllib3_integration.py | 28 +- .../instrumentation/wsgi/__init__.py | 14 +- .../tests/test_wsgi_middleware.py | 10 +- .../opentelemetry/instrumentation/_semconv.py | 113 +++++--- .../tests/test_semconv.py | 258 ++++++++++++++++++ 17 files changed, 422 insertions(+), 133 deletions(-) create mode 100644 opentelemetry-instrumentation/tests/test_semconv.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 106d9408c1..5c4c4452bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Add support to database stability opt-in in `_semconv` utilities and add tests + ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) + ### Fixed - `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints ([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105)) + ## Version 1.29.0/0.50b0 (2024-12-11) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index de60fa6379..c43522efe1 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -92,13 +92,13 @@ def response_hook(span: Span, params: typing.Union[ from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, _set_http_method, _set_http_url, _set_status, + _StabilityMode, ) from opentelemetry.instrumentation.aiohttp_client.package import _instruments from opentelemetry.instrumentation.aiohttp_client.version import __version__ @@ -142,7 +142,7 @@ def _set_http_status_code_attribute( span, status_code, metric_attributes=None, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): status_code_str = str(status_code) try: @@ -169,7 +169,7 @@ def create_trace_config( request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, tracer_provider: TracerProvider = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ) -> aiohttp.TraceConfig: """Create an aiohttp-compatible trace configuration. @@ -326,7 +326,7 @@ def _instrument( trace_configs: typing.Optional[ typing.Sequence[aiohttp.TraceConfig] ] = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): """Enables tracing of all ClientSessions diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py index 33b08fc0b6..62c837f88d 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py @@ -29,8 +29,8 @@ from opentelemetry.instrumentation import aiohttp_client from opentelemetry.instrumentation._semconv import ( OTEL_SEMCONV_STABILITY_OPT_IN, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, + _StabilityMode, ) from opentelemetry.instrumentation.aiohttp_client import ( AioHttpClientInstrumentor, @@ -150,7 +150,7 @@ def test_status_codes_new_semconv(self): path = "test-path?query=param#foobar" host, port = self._http_request( trace_config=aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + sem_conv_opt_in_mode=_StabilityMode.HTTP ), url=f"/{path}", status_code=status_code, @@ -173,7 +173,7 @@ def test_status_codes_both_semconv(self): path = "test-path?query=param#foobar" host, port = self._http_request( trace_config=aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP ), url=f"/{path}", status_code=status_code, @@ -213,7 +213,7 @@ def test_schema_url_new_semconv(self): with self.subTest(status_code=200): self._http_request( trace_config=aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + sem_conv_opt_in_mode=_StabilityMode.HTTP ), url="/test-path?query=param#foobar", status_code=200, @@ -230,7 +230,7 @@ def test_schema_url_both_semconv(self): with self.subTest(status_code=200): self._http_request( trace_config=aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP ), url="/test-path?query=param#foobar", status_code=200, @@ -398,7 +398,7 @@ async def request_handler(request): host, port = self._http_request( trace_config=aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + sem_conv_opt_in_mode=_StabilityMode.HTTP ), url="/test", request_handler=request_handler, @@ -426,7 +426,7 @@ async def request_handler(request): host, port = self._http_request( trace_config=aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP ), url="/test", request_handler=request_handler, @@ -546,7 +546,7 @@ async def do_request(url): def test_nonstandard_http_method_new_semconv(self): trace_configs = [ aiohttp_client.create_trace_config( - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + sem_conv_opt_in_mode=_StabilityMode.HTTP ) ] app = HttpServerMock("nonstandard_method") diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 725532bc15..b060095160 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -205,7 +205,6 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A _filter_semconv_active_request_count_attr, _filter_semconv_duration_attrs, _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, @@ -225,6 +224,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A _set_http_url, _set_http_user_agent, _set_status, + _StabilityMode, ) from opentelemetry.instrumentation.asgi.types import ( ClientRequestHook, @@ -324,7 +324,7 @@ def set(self, carrier: dict, key: str, value: str) -> None: # pylint: disable=n # pylint: disable=too-many-branches def collect_request_attributes( - scope, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + scope, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): """Collects HTTP request attributes from the ASGI scope and returns a dictionary to be used as span creation attributes.""" @@ -356,7 +356,7 @@ def collect_request_attributes( _set_http_url( result, remove_url_credentials(http_url), - _HTTPStabilityMode.DEFAULT, + _StabilityMode.DEFAULT, ) http_method = scope.get("method", "") if http_method: @@ -439,7 +439,7 @@ def set_status_code( span, status_code, metric_attributes=None, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): """Adds HTTP response attributes to span using the status_code argument.""" status_code_str = str(status_code) @@ -755,12 +755,12 @@ async def __call__( ) duration_s = default_timer() - start duration_attrs_old = _parse_duration_attrs( - attributes, _HTTPStabilityMode.DEFAULT + attributes, _StabilityMode.DEFAULT ) if target: duration_attrs_old[SpanAttributes.HTTP_TARGET] = target duration_attrs_new = _parse_duration_attrs( - attributes, _HTTPStabilityMode.HTTP + attributes, _StabilityMode.HTTP ) if self.duration_histogram_old: self.duration_histogram_old.record( @@ -960,7 +960,7 @@ async def otel_send(message: dict[str, Any]): def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): return _filter_semconv_duration_attrs( req_attrs, @@ -971,7 +971,7 @@ def _parse_duration_attrs( def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): return _filter_semconv_active_request_count_attr( req_attrs, diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index a9d7897ea6..6fcccf84ec 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -24,12 +24,12 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation._semconv import ( OTEL_SEMCONV_STABILITY_OPT_IN, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, _server_active_requests_count_attrs_old, _server_duration_attrs_new, _server_duration_attrs_old, + _StabilityMode, ) from opentelemetry.instrumentation.propagators import ( TraceResponsePropagator, @@ -1652,7 +1652,7 @@ def test_request_attributes_new_semconv(self): attrs = otel_asgi.collect_request_attributes( self.scope, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ) self.assertDictEqual( @@ -1677,7 +1677,7 @@ def test_request_attributes_both_semconv(self): attrs = otel_asgi.collect_request_attributes( self.scope, - _HTTPStabilityMode.HTTP_DUP, + _StabilityMode.HTTP_DUP, ) self.assertDictEqual( @@ -1715,7 +1715,7 @@ def test_query_string_new_semconv(self): self.scope["query_string"] = b"foo=bar" attrs = otel_asgi.collect_request_attributes( self.scope, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ) self.assertEqual(attrs[URL_SCHEME], "http") self.assertEqual(attrs[CLIENT_ADDRESS], "127.0.0.1") @@ -1726,7 +1726,7 @@ def test_query_string_both_semconv(self): self.scope["query_string"] = b"foo=bar" attrs = otel_asgi.collect_request_attributes( self.scope, - _HTTPStabilityMode.HTTP_DUP, + _StabilityMode.HTTP_DUP, ) self.assertEqual( attrs[SpanAttributes.HTTP_URL], "http://127.0.0.1/?foo=bar" @@ -1762,7 +1762,7 @@ def test_response_attributes_new_semconv(self): self.span, 404, None, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ) expected = (mock.call(HTTP_RESPONSE_STATUS_CODE, 404),) self.assertEqual(self.span.set_attribute.call_count, 1) @@ -1774,7 +1774,7 @@ def test_response_attributes_both_semconv(self): self.span, 404, None, - _HTTPStabilityMode.HTTP_DUP, + _StabilityMode.HTTP_DUP, ) expected = (mock.call(SpanAttributes.HTTP_STATUS_CODE, 404),) expected2 = (mock.call(HTTP_RESPONSE_STATUS_CODE, 404),) diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index da807cc310..f607046959 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -25,13 +25,13 @@ from opentelemetry.instrumentation._semconv import ( _filter_semconv_active_request_count_attr, _filter_semconv_duration_attrs, - _HTTPStabilityMode, _report_new, _report_old, _server_active_requests_count_attrs_new, _server_active_requests_count_attrs_old, _server_duration_attrs_new, _server_duration_attrs_old, + _StabilityMode, ) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, @@ -158,7 +158,7 @@ class _DjangoMiddleware(MiddlewareMixin): _duration_histogram_old = None _duration_histogram_new = None _active_request_counter = None - _sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT + _sem_conv_opt_in_mode = _StabilityMode.DEFAULT _otel_request_hook: Callable[[Span, HttpRequest], None] = None _otel_response_hook: Callable[[Span, HttpRequest, HttpResponse], None] = ( @@ -430,7 +430,7 @@ def process_response(self, request, response): duration_s = default_timer() - request_start_time if self._duration_histogram_old: duration_attrs_old = _parse_duration_attrs( - duration_attrs, _HTTPStabilityMode.DEFAULT + duration_attrs, _StabilityMode.DEFAULT ) # http.target to be included in old semantic conventions target = duration_attrs.get(SpanAttributes.HTTP_TARGET) @@ -441,7 +441,7 @@ def process_response(self, request, response): ) if self._duration_histogram_new: duration_attrs_new = _parse_duration_attrs( - duration_attrs, _HTTPStabilityMode.HTTP + duration_attrs, _StabilityMode.HTTP ) self._duration_histogram_new.record( max(duration_s, 0), duration_attrs_new @@ -455,7 +455,7 @@ def process_response(self, request, response): def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): return _filter_semconv_duration_attrs( req_attrs, @@ -466,7 +466,7 @@ def _parse_duration_attrs( def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): return _filter_semconv_active_request_count_attr( req_attrs, diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index 7e4d0aac07..a19480b234 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -186,9 +186,9 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry.instrumentation._semconv import ( _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, + _StabilityMode, ) from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.asgi.types import ( @@ -362,7 +362,7 @@ class _InstrumentedFastAPI(fastapi.FastAPI): _client_request_hook: ClientRequestHook = None _client_response_hook: ClientResponseHook = None _instrumented_fastapi_apps = set() - _sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT + _sem_conv_opt_in_mode = _StabilityMode.DEFAULT def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) 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 f80c0de808..9691f884ab 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -252,11 +252,11 @@ def response_hook(span: Span, status: str, response_headers: List): from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, _report_old, + _StabilityMode, ) from opentelemetry.instrumentation.flask.package import _instruments from opentelemetry.instrumentation.flask.version import __version__ @@ -321,7 +321,7 @@ def _rewrapped_app( duration_histogram_old=None, response_hook=None, excluded_urls=None, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, duration_histogram_new=None, ): def _wrapped_app(wrapped_app_environ, start_response): @@ -392,7 +392,7 @@ def _start_response(status, response_headers, *args, **kwargs): duration_s = default_timer() - start if duration_histogram_old: duration_attrs_old = otel_wsgi._parse_duration_attrs( - attributes, _HTTPStabilityMode.DEFAULT + attributes, _StabilityMode.DEFAULT ) if request_route: @@ -406,7 +406,7 @@ def _start_response(status, response_headers, *args, **kwargs): ) if duration_histogram_new: duration_attrs_new = otel_wsgi._parse_duration_attrs( - attributes, _HTTPStabilityMode.HTTP + attributes, _StabilityMode.HTTP ) if request_route: @@ -427,7 +427,7 @@ def _wrapped_before_request( excluded_urls=None, enable_commenter=True, commenter_options=None, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): def _before_request(): if excluded_urls and excluded_urls.url_disabled(flask.request.url): @@ -548,7 +548,7 @@ class _InstrumentedFlask(flask.Flask): _enable_commenter = True _commenter_options = None _meter_provider = None - _sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT + _sem_conv_opt_in_mode = _StabilityMode.DEFAULT def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index d4e7571f61..27bb3d639d 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -205,7 +205,6 @@ async def async_response_hook(span, request, response): from opentelemetry.instrumentation._semconv import ( _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, @@ -215,6 +214,7 @@ async def async_response_hook(span, request, response): _set_http_peer_port_client, _set_http_status_code, _set_http_url, + _StabilityMode, ) from opentelemetry.instrumentation.httpx.package import _instruments from opentelemetry.instrumentation.httpx.version import __version__ @@ -334,7 +334,7 @@ def _apply_request_client_attributes_to_span( span_attributes: dict, url: typing.Union[str, URL, httpx.URL], method_original: str, - semconv: _HTTPStabilityMode, + semconv: _StabilityMode, ): url = httpx.URL(url) # http semconv transition: http.method -> http.request.method @@ -363,7 +363,7 @@ def _apply_response_client_attributes_to_span( span: Span, status_code: int, http_version: str, - semconv: _HTTPStabilityMode, + semconv: _StabilityMode, ): # http semconv transition: http.status_code -> http.response.status_code # TODO: use _set_status when it's stable for http clients diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index db67d378d9..d1afa834d6 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -87,7 +87,6 @@ def response_hook(span, request_obj, response) _client_duration_attrs_old, _filter_semconv_duration_attrs, _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, @@ -100,6 +99,7 @@ def response_hook(span, request_obj, response) _set_http_scheme, _set_http_status_code, _set_http_url, + _StabilityMode, ) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.requests.package import _instruments @@ -147,7 +147,7 @@ def _instrument( request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, excluded_urls: ExcludeList = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): """Enables tracing of all requests calls that go through :code:`requests.session.Session.request` (this includes @@ -312,7 +312,7 @@ def get_or_create_headers(): metric_labels, _client_duration_attrs_old, _client_duration_attrs_new, - _HTTPStabilityMode.DEFAULT, + _StabilityMode.DEFAULT, ) duration_histogram_old.record( max(round(elapsed_time * 1000), 0), @@ -323,7 +323,7 @@ def get_or_create_headers(): metric_labels, _client_duration_attrs_old, _client_duration_attrs_new, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ) duration_histogram_new.record( elapsed_time, attributes=duration_attrs_new diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index 8b72a2f3db..9fe9996ba4 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -90,7 +90,6 @@ def response_hook(span, request_obj, response) _client_duration_attrs_old, _filter_semconv_duration_attrs, _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, @@ -99,6 +98,7 @@ def response_hook(span, request_obj, response) _set_http_network_protocol_version, _set_http_url, _set_status, + _StabilityMode, ) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.urllib.package import _instruments @@ -209,7 +209,7 @@ def _instrument( request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, excluded_urls: ExcludeList = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): """Enables tracing of all requests calls that go through :code:`urllib.Client._make_request`""" @@ -305,13 +305,13 @@ def _instrumented_open_call( labels, _client_duration_attrs_old, _client_duration_attrs_new, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ) duration_attrs_new = _filter_semconv_duration_attrs( labels, _client_duration_attrs_old, _client_duration_attrs_new, - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, + sem_conv_opt_in_mode=_StabilityMode.HTTP, ) duration_attrs_old[SpanAttributes.HTTP_URL] = url @@ -372,7 +372,7 @@ def _set_status_code_attribute( span: Span, status_code: int, metric_attributes: dict = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ) -> None: status_code_str = str(status_code) try: @@ -394,7 +394,7 @@ def _set_status_code_attribute( def _create_client_histograms( - meter, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + meter, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ) -> Dict[str, Histogram]: histograms = {} if _report_old(sem_conv_opt_in_mode): @@ -442,7 +442,7 @@ def _record_histograms( request_size: int, response_size: int, duration_s: float, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): if _report_old(sem_conv_opt_in_mode): duration = max(round(duration_s * 1000), 0) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index eda66bea37..2d1cf4c1b0 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -98,7 +98,6 @@ def response_hook( _client_duration_attrs_old, _filter_semconv_duration_attrs, _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, @@ -111,6 +110,7 @@ def response_hook( _set_http_scheme, _set_http_url, _set_status, + _StabilityMode, ) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.urllib3.package import _instruments @@ -309,7 +309,7 @@ def _instrument( response_hook: _ResponseHookT = None, url_filter: _UrlFilterT = None, excluded_urls: ExcludeList = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): def instrumented_urlopen(wrapped, instance, args, kwargs): if not is_http_instrumentation_enabled(): @@ -461,7 +461,7 @@ def _set_status_code_attribute( span: Span, status_code: int, metric_attributes: dict = None, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ) -> None: status_code_str = str(status_code) try: @@ -487,7 +487,7 @@ def _set_metric_attributes( instance: urllib3.connectionpool.HTTPConnectionPool, response: urllib3.response.HTTPResponse, method: str, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ) -> None: _set_http_host_client( metric_attributes, instance.host, sem_conv_opt_in_mode @@ -516,7 +516,7 @@ def _set_metric_attributes( def _filter_attributes_semconv( metric_attributes, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): duration_attrs_old = None duration_attrs_new = None @@ -525,14 +525,14 @@ def _filter_attributes_semconv( metric_attributes, _client_duration_attrs_old, _client_duration_attrs_new, - _HTTPStabilityMode.DEFAULT, + _StabilityMode.DEFAULT, ) if _report_new(sem_conv_opt_in_mode): duration_attrs_new = _filter_semconv_duration_attrs( metric_attributes, _client_duration_attrs_old, _client_duration_attrs_new, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ) return (duration_attrs_old, duration_attrs_new) @@ -549,7 +549,7 @@ def _record_metrics( duration_s: float, request_size: typing.Optional[int], response_size: int, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): attrs_old, attrs_new = _filter_attributes_semconv( metric_attributes, sem_conv_opt_in_mode diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py index 69bed0eaee..e5a9f3b7e1 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/tests/test_urllib3_integration.py @@ -24,8 +24,8 @@ from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( OTEL_SEMCONV_STABILITY_OPT_IN, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, + _StabilityMode, ) from opentelemetry.instrumentation.urllib3 import ( RequestInfo, @@ -106,7 +106,7 @@ def assert_success_span( self, response: urllib3.response.HTTPResponse, url: str, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): self.assertEqual(b"Hello!", response.data) @@ -129,9 +129,9 @@ def assert_success_span( } attributes = { - _HTTPStabilityMode.DEFAULT: expected_attr_old, - _HTTPStabilityMode.HTTP: expected_attr_new, - _HTTPStabilityMode.HTTP_DUP: { + _StabilityMode.DEFAULT: expected_attr_old, + _StabilityMode.HTTP: expected_attr_new, + _StabilityMode.HTTP_DUP: { **expected_attr_new, **expected_attr_old, }, @@ -143,7 +143,7 @@ def assert_success_span( def assert_exception_span( self, url: str, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): span = self.assert_span() @@ -159,9 +159,9 @@ def assert_exception_span( } attributes = { - _HTTPStabilityMode.DEFAULT: expected_attr_old, - _HTTPStabilityMode.HTTP: expected_attr_new, - _HTTPStabilityMode.HTTP_DUP: { + _StabilityMode.DEFAULT: expected_attr_old, + _StabilityMode.HTTP: expected_attr_new, + _StabilityMode.HTTP_DUP: { **expected_attr_new, **expected_attr_old, }, @@ -192,7 +192,7 @@ def test_basic_http_success(self): self.assert_success_span( response, self.HTTP_URL, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ) def test_basic_http_success_new_semconv(self): @@ -200,7 +200,7 @@ def test_basic_http_success_new_semconv(self): self.assert_success_span( response, self.HTTP_URL, - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, + sem_conv_opt_in_mode=_StabilityMode.HTTP, ) def test_basic_http_success_both_semconv(self): @@ -208,7 +208,7 @@ def test_basic_http_success_both_semconv(self): self.assert_success_span( response, self.HTTP_URL, - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP, + sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP, ) def test_basic_http_success_using_connection_pool(self): @@ -471,7 +471,7 @@ def test_request_exception_new_semconv(self, _): ) self.assert_exception_span( - self.HTTP_URL, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP + self.HTTP_URL, sem_conv_opt_in_mode=_StabilityMode.HTTP ) @mock.patch( @@ -485,7 +485,7 @@ def test_request_exception_both_semconv(self, _): ) self.assert_exception_span( - self.HTTP_URL, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP + self.HTTP_URL, sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP ) @mock.patch( diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index c0384d594b..eb7cbced9c 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -217,7 +217,6 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he _filter_semconv_active_request_count_attr, _filter_semconv_duration_attrs, _get_schema_url, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, @@ -237,6 +236,7 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he _set_http_target, _set_http_user_agent, _set_status, + _StabilityMode, ) from opentelemetry.instrumentation.utils import _start_internal_or_server_span from opentelemetry.instrumentation.wsgi.version import __version__ @@ -308,7 +308,7 @@ def setifnotnone(dic, key, value): def collect_request_attributes( environ, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): """Collects HTTP request attributes from the PEP3333-conforming WSGI environ and returns a dictionary to be used as span creation attributes. @@ -449,7 +449,7 @@ def _parse_status_code(resp_status): def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): return _filter_semconv_active_request_count_attr( req_attrs, @@ -460,7 +460,7 @@ def _parse_active_request_count_attrs( def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT ): return _filter_semconv_duration_attrs( req_attrs, @@ -475,7 +475,7 @@ def add_response_attributes( start_response_status, response_headers, duration_attrs=None, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): # pylint: disable=unused-argument """Adds HTTP response attributes to span using the arguments passed to a PEP3333-conforming start_response callable. @@ -685,14 +685,14 @@ def __call__(self, environ, start_response): duration_s = default_timer() - start if self.duration_histogram_old: duration_attrs_old = _parse_duration_attrs( - req_attrs, _HTTPStabilityMode.DEFAULT + req_attrs, _StabilityMode.DEFAULT ) self.duration_histogram_old.record( max(round(duration_s * 1000), 0), duration_attrs_old ) if self.duration_histogram_new: duration_attrs_new = _parse_duration_attrs( - req_attrs, _HTTPStabilityMode.HTTP + req_attrs, _StabilityMode.HTTP ) self.duration_histogram_new.record( max(duration_s, 0), duration_attrs_new diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py index 095e263732..da1a3c2696 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py @@ -24,12 +24,12 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation._semconv import ( OTEL_SEMCONV_STABILITY_OPT_IN, - _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, _server_active_requests_count_attrs_old, _server_duration_attrs_new, _server_duration_attrs_old, + _StabilityMode, ) from opentelemetry.sdk.metrics.export import ( HistogramDataPoint, @@ -527,7 +527,7 @@ def test_request_attributes_new_semconv(self): attrs = otel_wsgi.collect_request_attributes( self.environ, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ) self.assertDictEqual( attrs, @@ -742,7 +742,7 @@ def test_request_attributes_with_full_request_uri(self): self.assertGreaterEqual( otel_wsgi.collect_request_attributes( self.environ, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ).items(), expected_new.items(), ) @@ -758,7 +758,7 @@ def test_http_user_agent_attribute(self): self.assertGreaterEqual( otel_wsgi.collect_request_attributes( self.environ, - _HTTPStabilityMode.HTTP, + _StabilityMode.HTTP, ).items(), expected_new.items(), ) @@ -769,7 +769,7 @@ def test_response_attributes(self): self.span, "404 Not Found", {}, - sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, + sem_conv_opt_in_mode=_StabilityMode.HTTP, ) expected = (mock.call(SpanAttributes.HTTP_STATUS_CODE, 404),) expected_new = ( diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index c4e720fd04..091c876535 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -109,23 +109,23 @@ class _OpenTelemetryStabilitySignalType: HTTP = "http" + DATABASE = "database" -class _HTTPStabilityMode(Enum): - # http - emit the new, stable HTTP and networking conventions ONLY +class _StabilityMode(Enum): + DEFAULT = "default" HTTP = "http" - # http/dup - emit both the old and the stable HTTP and networking conventions HTTP_DUP = "http/dup" - # default - continue emitting old experimental HTTP and networking conventions - DEFAULT = "default" + DATABASE = "database" + DATABASE_DUP = "database/dup" -def _report_new(mode): - return mode.name != _HTTPStabilityMode.DEFAULT.name +def _report_new(mode: _StabilityMode): + return mode != _StabilityMode.DEFAULT -def _report_old(mode): - return mode.name != _HTTPStabilityMode.HTTP.name +def _report_old(mode: _StabilityMode): + return mode not in (_StabilityMode.HTTP, _StabilityMode.DATABASE) class _OpenTelemetrySemanticConventionStability: @@ -135,35 +135,61 @@ class _OpenTelemetrySemanticConventionStability: @classmethod def _initialize(cls): - with _OpenTelemetrySemanticConventionStability._lock: - if not _OpenTelemetrySemanticConventionStability._initialized: - # Users can pass in comma delimited string for opt-in options - # Only values for http stability are supported for now - opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN, "") - opt_in_list = [] - if opt_in: - opt_in_list = [s.strip() for s in opt_in.split(",")] - http_opt_in = _HTTPStabilityMode.DEFAULT - if opt_in_list: - # Process http opt-in - # http/dup takes priority over http - if _HTTPStabilityMode.HTTP_DUP.value in opt_in_list: - http_opt_in = _HTTPStabilityMode.HTTP_DUP - elif _HTTPStabilityMode.HTTP.value in opt_in_list: - http_opt_in = _HTTPStabilityMode.HTTP - _OpenTelemetrySemanticConventionStability._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[ - _OpenTelemetryStabilitySignalType.HTTP - ] = http_opt_in - _OpenTelemetrySemanticConventionStability._initialized = True + with cls._lock: + if cls._initialized: + return + + # Users can pass in comma delimited string for opt-in options + # Only values for http and database stability are supported for now + opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN) + + if not opt_in: + # early return in case of default + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = { + _OpenTelemetryStabilitySignalType.HTTP: _StabilityMode.DEFAULT, + _OpenTelemetryStabilitySignalType.DATABASE: _StabilityMode.DEFAULT, + } + cls._initialized = True + return + + opt_in_list = [s.strip() for s in opt_in.split(",")] + + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[ + _OpenTelemetryStabilitySignalType.HTTP + ] = cls._filter_mode( + opt_in_list, _StabilityMode.HTTP, _StabilityMode.HTTP_DUP + ) + + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[ + _OpenTelemetryStabilitySignalType.DATABASE + ] = cls._filter_mode( + opt_in_list, + _StabilityMode.DATABASE, + _StabilityMode.DATABASE_DUP, + ) + + cls._initialized = True + + @staticmethod + def _filter_mode(opt_in_list, stable_mode, dup_mode): + # Process semconv stability opt-in + # http/dup,database/dup has higher precedence over http,database + if dup_mode.value in opt_in_list: + return dup_mode + + return ( + stable_mode + if stable_mode.value in opt_in_list + else _StabilityMode.DEFAULT + ) @classmethod - # Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.) def _get_opentelemetry_stability_opt_in_mode( - cls, - signal_type: _OpenTelemetryStabilitySignalType, - ) -> _HTTPStabilityMode: - return _OpenTelemetrySemanticConventionStability._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get( - signal_type, _HTTPStabilityMode.DEFAULT + cls, signal_type: _OpenTelemetryStabilitySignalType + ) -> _StabilityMode: + # Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.) + return cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get( + signal_type, _StabilityMode.DEFAULT ) @@ -171,14 +197,12 @@ def _filter_semconv_duration_attrs( attrs, old_attrs, new_attrs, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): filtered_attrs = {} # duration is two different metrics depending on sem_conv_opt_in_mode, so no DUP attributes allowed_attributes = ( - new_attrs - if sem_conv_opt_in_mode == _HTTPStabilityMode.HTTP - else old_attrs + new_attrs if sem_conv_opt_in_mode == _StabilityMode.HTTP else old_attrs ) for key, val in attrs.items(): if key in allowed_attributes: @@ -190,7 +214,7 @@ def _filter_semconv_active_request_count_attr( attrs, old_attrs, new_attrs, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, ): filtered_attrs = {} if _report_old(sem_conv_opt_in_mode): @@ -367,10 +391,11 @@ def _set_status( status_code: int, status_code_str: str, server_span: bool = True, - sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): if status_code < 0: - metrics_attributes[ERROR_TYPE] = status_code_str + if _report_new(sem_conv_opt_in_mode): + metrics_attributes[ERROR_TYPE] = status_code_str if span.is_recording(): if _report_new(sem_conv_opt_in_mode): span.set_attribute(ERROR_TYPE, status_code_str) @@ -404,7 +429,7 @@ def _set_status( # Get schema version based off of opt-in mode -def _get_schema_url(mode: _HTTPStabilityMode) -> str: - if mode is _HTTPStabilityMode.DEFAULT: +def _get_schema_url(mode: _StabilityMode) -> str: + if mode is _StabilityMode.DEFAULT: return "https://opentelemetry.io/schemas/1.11.0" return SpanAttributes.SCHEMA_URL diff --git a/opentelemetry-instrumentation/tests/test_semconv.py b/opentelemetry-instrumentation/tests/test_semconv.py new file mode 100644 index 0000000000..6a56efcc37 --- /dev/null +++ b/opentelemetry-instrumentation/tests/test_semconv.py @@ -0,0 +1,258 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from unittest import TestCase +from unittest.mock import Mock, patch + +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _set_status, + _StabilityMode, +) +from opentelemetry.trace.status import StatusCode + + +def stability_mode(mode): + def decorator(test_case): + @patch.dict(os.environ, {OTEL_SEMCONV_STABILITY_OPT_IN: mode}) + def wrapper(*args, **kwargs): + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + return test_case(*args, **kwargs) + + return wrapper + + return decorator + + +class TestOpenTelemetrySemConvStability(TestCase): + @stability_mode("") + def test_default_mode(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.DEFAULT, + ) + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DEFAULT, + ) + + @stability_mode("http") + def test_http_stable_mode(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.HTTP, + ) + + @stability_mode("http/dup") + def test_http_dup_mode(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.HTTP_DUP, + ) + + @stability_mode("database") + def test_database_stable_mode(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DATABASE, + ) + + @stability_mode("database/dup") + def test_database_dup_mode(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DATABASE_DUP, + ) + + @stability_mode("database,http") + def test_multiple_stability_database_http_modes(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DATABASE, + ) + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.HTTP, + ) + + @stability_mode("database,http/dup") + def test_multiple_stability_database_http_dup_modes(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DATABASE, + ) + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.HTTP_DUP, + ) + + @stability_mode("database/dup,http") + def test_multiple_stability_database_dup_http_stable_modes(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DATABASE_DUP, + ) + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.HTTP, + ) + + @stability_mode("database,database/dup,http,http/dup") + def test_stability_mode_dup_precedence(self): + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE + ), + _StabilityMode.DATABASE_DUP, + ) + self.assertEqual( + _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP + ), + _StabilityMode.HTTP_DUP, + ) + + +class TestOpenTelemetrySemConvStabilityHTTP(TestCase): + def test_set_status_for_non_http_code_with_recording_span(self): + span = Mock() + span.is_recording.return_value = True + metric_attributes = {} + _set_status( + span, + metric_attributes, + -1, + "Exception", + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, + ) + + self.assertIsNone(metric_attributes.get("error.type")) + span.set_attribute.assert_not_called() + status_call = span.set_status.call_args[0][0] + self.assertEqual(status_call.status_code, StatusCode.ERROR) + self.assertEqual( + status_call.description, "Non-integer HTTP status: " + "Exception" + ) + + def test_status_code_http_default(self): + span = Mock() + metrics_attributes = {} + _set_status( + span=span, + metrics_attributes=metrics_attributes, + status_code=404, + status_code_str="404", + server_span=True, + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, + ) + # Verify only old conventions are emitted + span.set_attribute.assert_called_with("http.status_code", 404) + self.assertIn("http.status_code", metrics_attributes) + self.assertNotIn("http.response_status_code", metrics_attributes) + + def test_status_code_http_stable(self): + span = Mock() + metrics_attributes = {} + _set_status( + span=span, + metrics_attributes=metrics_attributes, + status_code=200, + status_code_str="200", + server_span=True, + sem_conv_opt_in_mode=_StabilityMode.HTTP, + ) + # Verify only new conventions are emitted + span.set_attribute.assert_called_with("http.response.status_code", 200) + self.assertIn("http.response.status_code", metrics_attributes) + self.assertNotIn("http.status_code", metrics_attributes) + + def test_status_code_http_dup(self): + span = Mock() + metrics_attributes = {} + _set_status( + span=span, + metrics_attributes=metrics_attributes, + status_code=500, + status_code_str="500", + server_span=True, + sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP, + ) + # Verify both old and new conventions are emitted + span.set_attribute.assert_any_call("http.status_code", 500) + span.set_attribute.assert_any_call("http.response.status_code", 500) + self.assertIn("http.status_code", metrics_attributes) + self.assertIn("http.response.status_code", metrics_attributes) + + def test_error_status_code_new_mode(self): + span = Mock() + metrics_attributes = {} + _set_status( + span=span, + metrics_attributes=metrics_attributes, + status_code=500, + status_code_str="500", + server_span=True, + sem_conv_opt_in_mode=_StabilityMode.HTTP, + ) + # Verify error type is set for new conventions + span.set_attribute.assert_any_call("error.type", "500") + self.assertIn("error.type", metrics_attributes) + self.assertEqual(metrics_attributes["error.type"], "500") + + def test_non_recording_span(self): + span = Mock() + span.is_recording.return_value = False + metrics_attributes = {} + _set_status( + span=span, + metrics_attributes=metrics_attributes, + status_code=200, + status_code_str="200", + server_span=True, + sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP, + ) + # Verify no span attributes are set if not recording + span.set_attribute.assert_not_called() + span.set_status.assert_not_called() + # Verify status code set for metrics independent of tracing decision + self.assertIn("http.status_code", metrics_attributes) + self.assertIn("http.response.status_code", metrics_attributes) From 6fcaa0a1048e3e26ddf7eb988e2e6f75258bf7dd Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 17 Dec 2024 19:40:40 +0100 Subject: [PATCH 283/335] Add type hints to Redis (#3110) --- .../instrumentation/redis/__init__.py | 105 +++++++++++++----- .../instrumentation/redis/py.typed | 0 2 files changed, 79 insertions(+), 26 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/py.typed diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index e81beb6f3d..8a3096ad41 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -91,8 +91,9 @@ def response_hook(span, instance, response): --- """ -import typing -from typing import Any, Collection +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Callable, Collection import redis from wrapt import wrap_function_wrapper @@ -109,18 +110,43 @@ def response_hook(span, instance, response): from opentelemetry.instrumentation.redis.version import __version__ from opentelemetry.instrumentation.utils import unwrap from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import Span, StatusCode +from opentelemetry.trace import Span, StatusCode, Tracer -_DEFAULT_SERVICE = "redis" +if TYPE_CHECKING: + from typing import Awaitable, TypeVar -_RequestHookT = typing.Optional[ - typing.Callable[ - [Span, redis.connection.Connection, typing.List, typing.Dict], None + import redis.asyncio.client + import redis.asyncio.cluster + import redis.client + import redis.cluster + import redis.connection + + _RequestHookT = Callable[ + [Span, redis.connection.Connection, list[Any], dict[str, Any]], None ] -] -_ResponseHookT = typing.Optional[ - typing.Callable[[Span, redis.connection.Connection, Any], None] -] + _ResponseHookT = Callable[[Span, redis.connection.Connection, Any], None] + + AsyncPipelineInstance = TypeVar( + "AsyncPipelineInstance", + redis.asyncio.client.Pipeline, + redis.asyncio.cluster.ClusterPipeline, + ) + AsyncRedisInstance = TypeVar( + "AsyncRedisInstance", redis.asyncio.Redis, redis.asyncio.RedisCluster + ) + PipelineInstance = TypeVar( + "PipelineInstance", + redis.client.Pipeline, + redis.cluster.ClusterPipeline, + ) + RedisInstance = TypeVar( + "RedisInstance", redis.client.Redis, redis.cluster.RedisCluster + ) + R = TypeVar("R") + + +_DEFAULT_SERVICE = "redis" + _REDIS_ASYNCIO_VERSION = (4, 2, 0) if redis.VERSION >= _REDIS_ASYNCIO_VERSION: @@ -132,7 +158,9 @@ def response_hook(span, instance, response): _FIELD_TYPES = ["NUMERIC", "TEXT", "GEO", "TAG", "VECTOR"] -def _set_connection_attributes(span, conn): +def _set_connection_attributes( + span: Span, conn: RedisInstance | AsyncRedisInstance +) -> None: if not span.is_recording() or not hasattr(conn, "connection_pool"): return for key, value in _extract_conn_attributes( @@ -141,7 +169,9 @@ def _set_connection_attributes(span, conn): span.set_attribute(key, value) -def _build_span_name(instance, cmd_args): +def _build_span_name( + instance: RedisInstance | AsyncRedisInstance, cmd_args: tuple[Any, ...] +) -> str: if len(cmd_args) > 0 and cmd_args[0]: if cmd_args[0] == "FT.SEARCH": name = "redis.search" @@ -154,7 +184,9 @@ def _build_span_name(instance, cmd_args): return name -def _build_span_meta_data_for_pipeline(instance): +def _build_span_meta_data_for_pipeline( + instance: PipelineInstance | AsyncPipelineInstance, +) -> tuple[list[Any], str, str]: try: command_stack = ( instance.command_stack @@ -184,11 +216,16 @@ def _build_span_meta_data_for_pipeline(instance): # pylint: disable=R0915 def _instrument( - tracer, - request_hook: _RequestHookT = None, - response_hook: _ResponseHookT = None, + tracer: Tracer, + request_hook: _RequestHookT | None = None, + response_hook: _ResponseHookT | None = None, ): - def _traced_execute_command(func, instance, args, kwargs): + def _traced_execute_command( + func: Callable[..., R], + instance: RedisInstance, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> R: query = _format_command_args(args) name = _build_span_name(instance, args) with tracer.start_as_current_span( @@ -210,7 +247,12 @@ def _traced_execute_command(func, instance, args, kwargs): response_hook(span, instance, response) return response - def _traced_execute_pipeline(func, instance, args, kwargs): + def _traced_execute_pipeline( + func: Callable[..., R], + instance: PipelineInstance, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> R: ( command_stack, resource, @@ -242,7 +284,7 @@ def _traced_execute_pipeline(func, instance, args, kwargs): return response - def _add_create_attributes(span, args): + def _add_create_attributes(span: Span, args: tuple[Any, ...]): _set_span_attribute_if_value( span, "redis.create_index.index", _value_or_none(args, 1) ) @@ -266,7 +308,7 @@ def _add_create_attributes(span, args): field_attribute, ) - def _add_search_attributes(span, response, args): + def _add_search_attributes(span: Span, response, args): _set_span_attribute_if_value( span, "redis.search.index", _value_or_none(args, 1) ) @@ -326,7 +368,12 @@ def _add_search_attributes(span, response, args): _traced_execute_pipeline, ) - async def _async_traced_execute_command(func, instance, args, kwargs): + async def _async_traced_execute_command( + func: Callable[..., Awaitable[R]], + instance: AsyncRedisInstance, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> Awaitable[R]: query = _format_command_args(args) name = _build_span_name(instance, args) @@ -344,7 +391,12 @@ async def _async_traced_execute_command(func, instance, args, kwargs): response_hook(span, instance, response) return response - async def _async_traced_execute_pipeline(func, instance, args, kwargs): + async def _async_traced_execute_pipeline( + func: Callable[..., Awaitable[R]], + instance: AsyncPipelineInstance, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> Awaitable[R]: ( command_stack, resource, @@ -408,14 +460,15 @@ async def _async_traced_execute_pipeline(func, instance, args, kwargs): class RedisInstrumentor(BaseInstrumentor): - """An instrumentor for Redis + """An instrumentor for Redis. + See `BaseInstrumentor` """ def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Instruments the redis module Args: @@ -436,7 +489,7 @@ def _instrument(self, **kwargs): response_hook=kwargs.get("response_hook"), ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): if redis.VERSION < (3, 0, 0): unwrap(redis.StrictRedis, "execute_command") unwrap(redis.StrictRedis, "pipeline") diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/py.typed b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 52ff7bdd4bf190428cc65b5874082a6bf5a3cf90 Mon Sep 17 00:00:00 2001 From: RJ Duffner Date: Tue, 17 Dec 2024 12:33:39 -0800 Subject: [PATCH 284/335] feat: Update opentelemetry-instrumentation-confluent-kafka to support confluent-kafka <=2.7.0 (#3100) --- CHANGELOG.md | 2 ++ instrumentation/README.md | 2 +- .../pyproject.toml | 2 +- .../opentelemetry/instrumentation/confluent_kafka/package.py | 2 +- .../test-requirements.txt | 2 +- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c4c4452bc..a243091b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-confluent-kafka` Add support for confluent-kafka <=2.7.0 + ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) diff --git a/instrumentation/README.md b/instrumentation/README.md index bff37fde6c..b12ac1aa21 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -16,7 +16,7 @@ | [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | experimental | [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | experimental | [opentelemetry-instrumentation-click](./opentelemetry-instrumentation-click) | click >= 8.1.3, < 9.0.0 | No | experimental -| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.4.0 | No | experimental +| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.7.0 | No | experimental | [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | experimental | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 74be18efca..c1ec1f696b 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "confluent-kafka >= 1.8.2, <= 2.4.0", + "confluent-kafka >= 1.8.2, <= 2.7.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py index 6ebddd30ac..7b5c10ba14 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py @@ -13,4 +13,4 @@ # limitations under the License. -_instruments = ("confluent-kafka >= 1.8.2, <= 2.4.0",) +_instruments = ("confluent-kafka >= 1.8.2, <= 2.7.0",) diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 88b5bbe680..be0142a36b 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -1,5 +1,5 @@ asgiref==3.8.1 -confluent-kafka==2.4.0 +confluent-kafka==2.6.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index cffc612662..4e497b8208 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -77,7 +77,7 @@ "instrumentation": "opentelemetry-instrumentation-click==0.51b0.dev", }, { - "library": "confluent-kafka >= 1.8.2, <= 2.4.0", + "library": "confluent-kafka >= 1.8.2, <= 2.7.0", "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.51b0.dev", }, { From 1ddba1b5189bf546f48ef8af6139c473a8f32002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:05:29 -0300 Subject: [PATCH 285/335] contributing: add guidance on how to update package versions support (#3090) * contributing: add guidance for update package versions support Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * update the guide Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * Update CONTRIBUTING.md * Update CONTRIBUTING.md Co-authored-by: Riccardo Magliocchetti * Update CONTRIBUTING.md Co-authored-by: Riccardo Magliocchetti * Update CONTRIBUTING.md to add docs instructions * Update CONTRIBUTING.md * Update CONTRIBUTING.md --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CONTRIBUTING.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e90402edc2..ab22d3821f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,7 +63,7 @@ You can run `tox` with the following arguments: * `tox` to run all existing tox commands, including unit tests for all packages under multiple Python versions -* `tox -e docs` to regenerate the API docs +* `tox -e docs` to regenerate all docs * `tox -e py312-test-instrumentation-aiopg` to e.g. run the aiopg instrumentation unit tests under a specific Python version * `tox -e spellcheck` to run a spellcheck on all the code @@ -89,7 +89,9 @@ for more detail on available tox commands. ### Troubleshooting -> Some packages may require additional system wide dependencies to be installed. For example, you may need to install `libpq-dev` to run the postgresql client libraries instrumentation tests. or `libsnappy-dev` to run the prometheus exporter tests. If you encounter a build error, please check the installation instructions for the package you are trying to run tests for. +Some packages may require additional system-wide dependencies to be installed. For example, you may need to install `libpq-dev` to run the postgresql client libraries instrumentation tests or `libsnappy-dev` to run the prometheus exporter tests. If you encounter a build error, please check the installation instructions for the package you are trying to run tests for. + +For `docs` building, you may need to install `mysql-client` and other required dependencies as necessary. Ensure the Python version used in your local setup matches the version used in the [CI](./.github/workflows/) to maintain compatibility when building the documentation. ### Benchmarks @@ -278,6 +280,20 @@ Below is a checklist of things to be mindful of when implementing a new instrume - Testing - When adding a new instrumentation remember to update `tox.ini` adding appropriate rules in `envlist`, `command_pre` and `commands` sections +### Update supported instrumentation package versions + +- Navigate to the **instrumentation package directory:** + - Update **`pyproject.toml`** file by modifying _instruments_ entry in the `[project.optional-dependencies]` section with the new version constraint + - Update `_instruments` variable in instrumentation **`package.py`** file with the new version constraint +- At the **root of the project directory**, run `tox -e generate` to regenerate necessary files + +If you're adding support for a new version of the instrumentation package, follow these additional steps: + +- At the **instrumentation package directory:** Add new test-requirements.txt file with the respective package version required for testing +- At the **root of the project directory**: Add a new test environment entry for the package version in [tox.ini](./tox.ini) and run `tox -e generate-workflows` to regenerate new workflows accordingly. In the same [tox.ini](./tox.ini) file, search for `opentelemetry-instrumentation-{package}/test-requirements` and add a new line to point to the new test-requirements.txt you created in the previous step so tox can install the correct requirements. + +Example PRs: [#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976), [#2845](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2845) + ## Guideline for GenAI instrumentations Instrumentations that relate to [Generative AI](https://opentelemetry.io/docs/specs/semconv/gen-ai/) systems will be placed in the [instrumentation-genai](./instrumentation-genai) folder. This section covers contributions related to those instrumentations. Please note that the [guidelines for instrumentations](#guideline-for-instrumentations) and [expectations from contributors](#expectations-from-contributors) still apply. From 54cbf59aaef7cc2ebe52521eb56c19dd23af7c61 Mon Sep 17 00:00:00 2001 From: Andrea Galbusera Date: Thu, 19 Dec 2024 11:15:58 +0100 Subject: [PATCH 286/335] Update package metadata adding "Repository" to project urls (#3119) Add "Repository" label to project urls pointing to the opentelemetry-python repo root url. Having within project urls one entry with the same value for all packages released by the project will help tools for automatic dependency management to suggest coherent upgrades for related packages. --- _template/pyproject.toml | 1 + .../pyproject.toml | 1 + exporter/opentelemetry-exporter-richconsole/pyproject.toml | 1 + .../opentelemetry-instrumentation-openai-v2/pyproject.toml | 1 + .../opentelemetry-instrumentation-aio-pika/pyproject.toml | 1 + .../opentelemetry-instrumentation-aiohttp-client/pyproject.toml | 1 + .../opentelemetry-instrumentation-aiohttp-server/pyproject.toml | 1 + .../opentelemetry-instrumentation-aiokafka/pyproject.toml | 1 + .../opentelemetry-instrumentation-aiopg/pyproject.toml | 1 + .../opentelemetry-instrumentation-asgi/pyproject.toml | 1 + .../opentelemetry-instrumentation-asyncio/pyproject.toml | 1 + .../opentelemetry-instrumentation-asyncpg/pyproject.toml | 1 + .../opentelemetry-instrumentation-aws-lambda/pyproject.toml | 1 + .../opentelemetry-instrumentation-boto/pyproject.toml | 1 + .../opentelemetry-instrumentation-boto3sqs/pyproject.toml | 1 + .../opentelemetry-instrumentation-botocore/pyproject.toml | 1 + .../opentelemetry-instrumentation-cassandra/pyproject.toml | 1 + .../opentelemetry-instrumentation-celery/pyproject.toml | 1 + .../opentelemetry-instrumentation-click/pyproject.toml | 1 + .../opentelemetry-instrumentation-confluent-kafka/pyproject.toml | 1 + .../opentelemetry-instrumentation-dbapi/pyproject.toml | 1 + .../opentelemetry-instrumentation-django/pyproject.toml | 1 + .../opentelemetry-instrumentation-elasticsearch/pyproject.toml | 1 + .../opentelemetry-instrumentation-falcon/pyproject.toml | 1 + .../opentelemetry-instrumentation-fastapi/pyproject.toml | 1 + .../opentelemetry-instrumentation-flask/pyproject.toml | 1 + .../opentelemetry-instrumentation-grpc/pyproject.toml | 1 + .../opentelemetry-instrumentation-httpx/pyproject.toml | 1 + .../opentelemetry-instrumentation-jinja2/pyproject.toml | 1 + .../opentelemetry-instrumentation-kafka-python/pyproject.toml | 1 + .../opentelemetry-instrumentation-logging/pyproject.toml | 1 + .../opentelemetry-instrumentation-mysql/pyproject.toml | 1 + .../opentelemetry-instrumentation-mysqlclient/pyproject.toml | 1 + .../opentelemetry-instrumentation-pika/pyproject.toml | 1 + .../opentelemetry-instrumentation-psycopg/pyproject.toml | 1 + .../opentelemetry-instrumentation-psycopg2/pyproject.toml | 1 + .../opentelemetry-instrumentation-pymemcache/pyproject.toml | 1 + .../opentelemetry-instrumentation-pymongo/pyproject.toml | 1 + .../opentelemetry-instrumentation-pymysql/pyproject.toml | 1 + .../opentelemetry-instrumentation-pyramid/pyproject.toml | 1 + .../opentelemetry-instrumentation-redis/pyproject.toml | 1 + .../opentelemetry-instrumentation-remoulade/pyproject.toml | 1 + .../opentelemetry-instrumentation-requests/pyproject.toml | 1 + .../opentelemetry-instrumentation-sqlalchemy/pyproject.toml | 1 + .../opentelemetry-instrumentation-sqlite3/pyproject.toml | 1 + .../opentelemetry-instrumentation-starlette/pyproject.toml | 1 + .../opentelemetry-instrumentation-system-metrics/pyproject.toml | 1 + .../opentelemetry-instrumentation-threading/pyproject.toml | 1 + .../opentelemetry-instrumentation-tornado/pyproject.toml | 1 + .../opentelemetry-instrumentation-tortoiseorm/pyproject.toml | 1 + .../opentelemetry-instrumentation-urllib/pyproject.toml | 1 + .../opentelemetry-instrumentation-urllib3/pyproject.toml | 1 + .../opentelemetry-instrumentation-wsgi/pyproject.toml | 1 + opentelemetry-contrib-instrumentations/pyproject.toml | 1 + opentelemetry-distro/pyproject.toml | 1 + opentelemetry-instrumentation/pyproject.toml | 1 + processor/opentelemetry-processor-baggage/pyproject.toml | 1 + propagator/opentelemetry-propagator-aws-xray/pyproject.toml | 1 + propagator/opentelemetry-propagator-ot-trace/pyproject.toml | 1 + resource/opentelemetry-resource-detector-azure/pyproject.toml | 1 + .../opentelemetry-resource-detector-container/pyproject.toml | 1 + sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml | 1 + util/opentelemetry-util-http/pyproject.toml | 1 + 63 files changed, 63 insertions(+) diff --git a/_template/pyproject.toml b/_template/pyproject.toml index b180d32ad8..bb60cb1578 100644 --- a/_template/pyproject.toml +++ b/_template/pyproject.toml @@ -41,6 +41,7 @@ REPLACE_ME = "opentelemetry.instrumentation." # url of the instrumentation e.g # Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-sqlalchemy" Homepage = "" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] # REPLACE ME: the path to the version file e.g diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml index 4218e13472..78db2c6cb5 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/exporter/opentelemetry-exporter-prometheus-remote-write" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/exporter/prometheus_remote_write/version.py" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 2d001c9f6e..140e6c6080 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -33,6 +33,7 @@ dependencies = [ [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/exporter/opentelemetry-exporter-richconsole" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/exporter/richconsole/version.py" diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index f37b6915e3..88e559a511 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -40,6 +40,7 @@ openai = "opentelemetry.instrumentation.openai_v2:OpenAIInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-openai-v2" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/openai_v2/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index de0f7e6a71..3e21377aff 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -40,6 +40,7 @@ aio-pika = "opentelemetry.instrumentation.aio_pika:AioPikaInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aio-pika" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/aio_pika/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index 7fcb829bc6..4d2d626786 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -42,6 +42,7 @@ aiohttp-client = "opentelemetry.instrumentation.aiohttp_client:AioHttpClientInst [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiohttp-client" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/aiohttp_client/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 5e098e38b6..7b0cf4c501 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -42,6 +42,7 @@ aiohttp-server = "opentelemetry.instrumentation.aiohttp_server:AioHttpServerInst [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiohttp-server" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/aiohttp_server/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index a3fb3c15be..0787695f26 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -38,6 +38,7 @@ aiokafka = "opentelemetry.instrumentation.aiokafka:AIOKafkaInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiokafka" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/aiokafka/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 13659d6a73..4b55ea8dfe 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -41,6 +41,7 @@ aiopg = "opentelemetry.instrumentation.aiopg:AiopgInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiopg" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/aiopg/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 69378faf78..40a9e3e49b 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -39,6 +39,7 @@ instruments = [ [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-asgi" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/asgi/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index b948a18067..279b2709b4 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -39,6 +39,7 @@ asyncio = "opentelemetry.instrumentation.asyncio:AsyncioInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-asyncio" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/asyncio/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index e4542789b9..9ba7a060d5 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -40,6 +40,7 @@ asyncpg = "opentelemetry.instrumentation.asyncpg:AsyncPGInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-asyncpg" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/asyncpg/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index 4ddc85072f..a5f9f44f13 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -38,6 +38,7 @@ aws-lambda = "opentelemetry.instrumentation.aws_lambda:AwsLambdaInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aws-lambda" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/aws_lambda/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index c898e65dad..065e8ec79d 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -39,6 +39,7 @@ boto = "opentelemetry.instrumentation.boto:BotoInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-boto" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/boto/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 4341f2fab6..6f24df391b 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -41,6 +41,7 @@ boto3 = "opentelemetry.instrumentation.boto3sqs:Boto3SQSInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-boto3sqs" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/boto3sqs/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index f0e666d443..ddf246a114 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -41,6 +41,7 @@ botocore = "opentelemetry.instrumentation.botocore:BotocoreInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-botocore" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/botocore/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 79ba6ca83a..771199ddfa 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -42,6 +42,7 @@ cassandra = "opentelemetry.instrumentation.cassandra:CassandraInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-cassandra" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/cassandra/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 0355940416..6f37573860 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -40,6 +40,7 @@ celery = "opentelemetry.instrumentation.celery:CeleryInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-celery" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/celery/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index f78c8ff605..43a95f5cae 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -40,6 +40,7 @@ click = "opentelemetry.instrumentation.click:ClickInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-click" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/click/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index c1ec1f696b..2694dcedc7 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -40,6 +40,7 @@ confluent_kafka = "opentelemetry.instrumentation.confluent_kafka:ConfluentKafkaI [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-confluent-kafka" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/confluent_kafka/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index 363f8e1cea..8b4e96ba32 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -36,6 +36,7 @@ instruments = [] [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-dbapi" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/dbapi/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index 7a68a6206e..27b5865033 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -45,6 +45,7 @@ django = "opentelemetry.instrumentation.django:DjangoInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-django" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/django/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 051eb4d4a0..7a8899bd14 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -41,6 +41,7 @@ elasticsearch = "opentelemetry.instrumentation.elasticsearch:ElasticsearchInstru [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-elasticsearch" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/elasticsearch/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 353020c014..883c76a9fd 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -43,6 +43,7 @@ falcon = "opentelemetry.instrumentation.falcon:FalconInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-falcon" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/falcon/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index ec5f3bedf4..34e3450540 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -42,6 +42,7 @@ fastapi = "opentelemetry.instrumentation.fastapi:FastAPIInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-fastapi" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/fastapi/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index f6ffbc8079..c0945a8935 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -43,6 +43,7 @@ flask = "opentelemetry.instrumentation.flask:FlaskInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-flask" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/flask/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index b776422690..c1239d7ebd 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -44,6 +44,7 @@ grpc_aio_server = "opentelemetry.instrumentation.grpc:GrpcAioInstrumentorServer" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-grpc" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/grpc/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 255cea485a..1138704387 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -42,6 +42,7 @@ httpx = "opentelemetry.instrumentation.httpx:HTTPXClientInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-httpx" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/httpx/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index 10fb75e60c..9c853efd52 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -40,6 +40,7 @@ jinja2 = "opentelemetry.instrumentation.jinja2:Jinja2Instrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-jinja2" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/jinja2/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index e2249ce07c..a6868816c0 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -41,6 +41,7 @@ kafka = "opentelemetry.instrumentation.kafka:KafkaInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-kafka-python" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/kafka/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 365539701e..ef1442b574 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -37,6 +37,7 @@ logging = "opentelemetry.instrumentation.logging:LoggingInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-logging" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/logging/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 1bfecd2183..6e74ba69b6 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -40,6 +40,7 @@ mysql = "opentelemetry.instrumentation.mysql:MySQLInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-mysql" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/mysql/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index 4311f6b610..2b827f8667 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -40,6 +40,7 @@ mysqlclient = "opentelemetry.instrumentation.mysqlclient:MySQLClientInstrumentor [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-mysqlclient" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/mysqlclient/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 8fadfad325..655cb5a7ee 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -41,6 +41,7 @@ pika = "opentelemetry.instrumentation.pika:PikaInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-pika" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/pika/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 363ae2807e..e2cf929371 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -41,6 +41,7 @@ psycopg = "opentelemetry.instrumentation.psycopg:PsycopgInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-psycopg" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/psycopg/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 0e30861d6f..d73fbc020a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -40,6 +40,7 @@ psycopg2 = "opentelemetry.instrumentation.psycopg2:Psycopg2Instrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-psycopg2" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/psycopg2/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index f875c409d8..6da560c333 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -41,6 +41,7 @@ pymemcache = "opentelemetry.instrumentation.pymemcache:PymemcacheInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-pymemcache" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/pymemcache/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index 8a3a971790..55926c5591 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -40,6 +40,7 @@ pymongo = "opentelemetry.instrumentation.pymongo:PymongoInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-pymongo" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/pymongo/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index c5f9b9955d..a806ff9ce4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -40,6 +40,7 @@ pymysql = "opentelemetry.instrumentation.pymysql:PyMySQLInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-pymysql" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/pymysql/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index d7289f4e42..c72a22a53e 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -43,6 +43,7 @@ pyramid = "opentelemetry.instrumentation.pyramid:PyramidInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-pyramid" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/pyramid/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 00b44d2366..4ffaeef263 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -41,6 +41,7 @@ redis = "opentelemetry.instrumentation.redis:RedisInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-redis" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/redis/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 97db24e18f..76ad80c786 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -40,6 +40,7 @@ remoulade = "opentelemetry.instrumentation.remoulade:RemouladeInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-remoulade" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/remoulade/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index a8a7792cc3..e4c5e63742 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -41,6 +41,7 @@ requests = "opentelemetry.instrumentation.requests:RequestsInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-requests" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/requests/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index 17c3095bf5..1c758e19e8 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -42,6 +42,7 @@ sqlalchemy = "opentelemetry.instrumentation.sqlalchemy:SQLAlchemyInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-sqlalchemy" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/sqlalchemy/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index 40e5b140af..d10a280c47 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -38,6 +38,7 @@ sqlite3 = "opentelemetry.instrumentation.sqlite3:SQLite3Instrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-sqlite3" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/sqlite3/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 4be53c57ab..6a0a011245 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -42,6 +42,7 @@ starlette = "opentelemetry.instrumentation.starlette:StarletteInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-starlette" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/starlette/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index e8bc8375fd..867c21a8d4 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -40,6 +40,7 @@ system_metrics = "opentelemetry.instrumentation.system_metrics:SystemMetricsInst [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-system-metrics" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/system_metrics/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 5c0efc09aa..59aeb4e6b4 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -38,6 +38,7 @@ threading = "opentelemetry.instrumentation.threading:ThreadingInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-threading" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/threading/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index 18104a99c4..b20805fa3c 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -40,6 +40,7 @@ tornado = "opentelemetry.instrumentation.tornado:TornadoInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-tornado" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/tornado/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index c83d9fbd5f..71dfe82508 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -41,6 +41,7 @@ tortoiseorm = "opentelemetry.instrumentation.tortoiseorm:TortoiseORMInstrumentor [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-tortoiseorm" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/tortoiseorm/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 71ecc981c1..62e272a4d1 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -39,6 +39,7 @@ urllib = "opentelemetry.instrumentation.urllib:URLLibInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-urllib" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/urllib/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 70a6183d99..214d3e8fb8 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -42,6 +42,7 @@ urllib3 = "opentelemetry.instrumentation.urllib3:URLLib3Instrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-urllib3" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/urllib3/version.py" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index ed9fd9bf24..1e6a85f758 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -36,6 +36,7 @@ instruments = [] [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-wsgi" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/wsgi/version.py" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 36aec6a5c5..bded7f840a 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -82,6 +82,7 @@ dependencies = [ [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-contrib-instrumentations" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/contrib-instrumentations/version.py" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 32c06ca723..3acea19815 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -44,6 +44,7 @@ distro = "opentelemetry.distro:OpenTelemetryDistro" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-distro" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/distro/version.py" diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index 616c22f7e9..54e717d4c8 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -40,6 +40,7 @@ instrumentation = "opentelemetry.instrumentation.environment_variables" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/instrumentation/version.py" diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 29fc2e8681..6e9681fe99 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -32,6 +32,7 @@ dependencies = [ [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/processor/opentelemetry-processor-baggage" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/processor/baggage/version.py" diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 14f16409b3..0307db4a8e 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -34,6 +34,7 @@ xray-lambda = "opentelemetry.propagators.aws:AwsXRayLambdaPropagator" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/propagator/opentelemetry-propagator-aws-xray" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/propagators/aws/version.py" diff --git a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml index 93c7ad6784..5793d55870 100644 --- a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml +++ b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml @@ -34,6 +34,7 @@ ottrace = "opentelemetry.propagators.ot_trace:OTTracePropagator" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/propagator/opentelemetry-propagator-ot-trace" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/propagators/ot_trace/version.py" diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index 9427a1bee4..a1bd1dc37c 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -36,6 +36,7 @@ azure_vm = "opentelemetry.resource.detector.azure.vm:AzureVMResourceDetector" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/resource/opentelemetry-resource-detector-azure" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/resource/detector/azure/version.py" diff --git a/resource/opentelemetry-resource-detector-container/pyproject.toml b/resource/opentelemetry-resource-detector-container/pyproject.toml index 3993ecd06c..ba38089465 100644 --- a/resource/opentelemetry-resource-detector-container/pyproject.toml +++ b/resource/opentelemetry-resource-detector-container/pyproject.toml @@ -33,6 +33,7 @@ container = "opentelemetry.resource.detector.container:ContainerResourceDetector [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/resource/opentelemetry-resource-detector-container" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/resource/detector/container/version.py" diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml index 767bebdd10..fb7e4cecf2 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml +++ b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml @@ -40,6 +40,7 @@ aws_lambda = "opentelemetry.sdk.extension.aws.resource._lambda:AwsLambdaResource [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/sdk-extension/opentelemetry-sdk-extension-aws" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/sdk/extension/aws/version.py" diff --git a/util/opentelemetry-util-http/pyproject.toml b/util/opentelemetry-util-http/pyproject.toml index 0e632a81b3..23b4d3efc1 100644 --- a/util/opentelemetry-util-http/pyproject.toml +++ b/util/opentelemetry-util-http/pyproject.toml @@ -27,6 +27,7 @@ classifiers = [ [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/util/opentelemetry-util-http" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" [tool.hatch.version] path = "src/opentelemetry/util/http/version.py" From 1092344918675819203972473423ccaf6df5f544 Mon Sep 17 00:00:00 2001 From: Beijie Zhang <98988442+beijiez@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:24:46 -0500 Subject: [PATCH 287/335] Add docstring for instrument_connection() and tests for database drivers (#3108) --- .../instrumentation/aiopg/__init__.py | 19 ++++++- .../instrumentation/mysql/__init__.py | 28 ++++++++-- .../instrumentation/mysqlclient/__init__.py | 52 ++++++++++++++++--- .../instrumentation/psycopg/__init__.py | 30 ++++++++++- .../instrumentation/psycopg2/__init__.py | 31 ++++++++++- .../instrumentation/pymysql/__init__.py | 41 +++++++++++++-- .../instrumentation/sqlite3/__init__.py | 24 +++++++-- .../tests/test_sqlite3.py | 17 ++++++ 8 files changed, 221 insertions(+), 21 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/__init__.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/__init__.py index 1d51d14d5b..3a28c0aab1 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/__init__.py @@ -25,22 +25,39 @@ import aiopg from opentelemetry.instrumentation.aiopg import AiopgInstrumentor - + # Call instrument() to wrap all database connections AiopgInstrumentor().instrument() cnx = await aiopg.connect(database='Database') cursor = await cnx.cursor() + await cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") await cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() pool = await aiopg.create_pool(database='Database') + cnx = await pool.acquire() cursor = await cnx.cursor() + await cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") await cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() +.. code-block:: python + + import aiopg + from opentelemetry.instrumentation.aiopg import AiopgInstrumentor + + # Alternatively, use instrument_connection for an individual connection + cnx = await aiopg.connect(database='Database') + instrumented_cnx = AiopgInstrumentor().instrument_connection(cnx) + cursor = await instrumented_cnx.cursor() + await cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") + await cursor.execute("INSERT INTO test (testField) VALUES (123)") + cursor.close() + instrumented_cnx.close() + API --- """ diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py index d88dffde2b..0116dab1c3 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py @@ -26,14 +26,30 @@ import mysql.connector from opentelemetry.instrumentation.mysql import MySQLInstrumentor + # Call instrument() to wrap all database connections MySQLInstrumentor().instrument() cnx = mysql.connector.connect(database="MySQL_Database") cursor = cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() +.. code:: python + + import mysql.connector + from opentelemetry.instrumentation.mysql import MySQLInstrumentor + + # Alternatively, use instrument_connection for an individual connection + cnx = mysql.connector.connect(database="MySQL_Database") + instrumented_cnx = MySQLInstrumentor().instrument_connection(cnx) + cursor = instrumented_cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") + cursor.execute("INSERT INTO test (testField) VALUES (123)") + cursor.close() + instrumented_cnx.close() + API --- """ @@ -86,12 +102,16 @@ def instrument_connection(self, connection, tracer_provider=None): """Enable instrumentation in a MySQL connection. Args: - connection: The connection to instrument. - tracer_provider: The optional tracer provider to use. If omitted - the current globally configured one is used. + connection: + The existing MySQL connection instance to instrument. This connection is typically + obtained through `mysql.connector.connect()` and is instrumented to collect telemetry + data about database interactions. + tracer_provider: + An optional `TracerProvider` instance to use for tracing. If not provided, the globally + configured tracer provider will be automatically used. Returns: - An instrumented connection. + An instrumented MySQL connection with OpenTelemetry tracing enabled. """ return dbapi.instrument_connection( __name__, diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py index 5b08b0b50d..e1c07096fa 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py @@ -46,16 +46,40 @@ import MySQLdb from opentelemetry.instrumentation.mysqlclient import MySQLClientInstrumentor - + # Call instrument() to wrap all database connections MySQLClientInstrumentor().instrument(enable_commenter=True, commenter_options={}) cnx = MySQLdb.connect(database="MySQL_Database") cursor = cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") cursor.execute("INSERT INTO test (testField) VALUES (123)" cnx.commit() cursor.close() cnx.close() +.. code:: python + + import MySQLdb + from opentelemetry.instrumentation.mysqlclient import MySQLClientInstrumentor + + # Alternatively, use instrument_connection for an individual connection + cnx = MySQLdb.connect(database="MySQL_Database") + instrumented_cnx = MySQLClientInstrumentor().instrument_connection( + cnx, + enable_commenter=True, + commenter_options={ + "db_driver": True, + "mysql_client_version": True, + "driver_paramstyle": False + } + ) + cursor = instrumented_cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") + cursor.execute("INSERT INTO test (testField) VALUES (123)" + instrumented_cnx.commit() + cursor.close() + instrumented_cnx.close() + For example, :: @@ -162,12 +186,28 @@ def instrument_connection( """Enable instrumentation in a mysqlclient connection. Args: - connection: The connection to instrument. - tracer_provider: The optional tracer provider to use. If omitted - the current globally configured one is used. - + connection: + The MySQL connection instance to instrument. This connection is typically + created using `MySQLdb.connect()` and needs to be wrapped to collect telemetry. + tracer_provider: + A custom `TracerProvider` instance to be used for tracing. If not specified, + the globally configured tracer provider will be used. + enable_commenter: + A flag to enable the OpenTelemetry SQLCommenter feature. If set to `True`, + SQL queries will be enriched with contextual information (e.g., database client details). + Default is `None`. + commenter_options: + A dictionary of configuration options for SQLCommenter. All options are enabled (True) by default. + This allows you to customize metadata appended to queries. Possible options include: + + - `db_driver`: Adds the database driver name and version. + - `dbapi_threadsafety`: Adds threadsafety information. + - `dbapi_level`: Adds the DB-API version. + - `mysql_client_version`: Adds the MySQL client version. + - `driver_paramstyle`: Adds the parameter style. + - `opentelemetry_values`: Includes traceparent values. Returns: - An instrumented connection. + An instrumented MySQL connection with OpenTelemetry support enabled. """ return dbapi.instrument_connection( diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py index e986ec0d46..8c608b7655 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py @@ -88,15 +88,31 @@ import psycopg from opentelemetry.instrumentation.psycopg import PsycopgInstrumentor - + # Call instrument() to wrap all database connections PsycopgInstrumentor().instrument() cnx = psycopg.connect(database='Database') + cursor = cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() +.. code-block:: python + + import psycopg + from opentelemetry.instrumentation.psycopg import PsycopgInstrumentor + + # Alternatively, use instrument_connection for an individual connection + cnx = psycopg.connect(database='Database') + instrumented_cnx = PsycopgInstrumentor().instrument_connection(cnx) + cursor = instrumented_cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") + cursor.execute("INSERT INTO test (testField) VALUES (123)") + cursor.close() + instrumented_cnx.close() + API --- """ @@ -196,6 +212,18 @@ def _uninstrument(self, **kwargs): # TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql @staticmethod def instrument_connection(connection, tracer_provider=None): + """Enable instrumentation in a psycopg connection. + + Args: + connection: psycopg.Connection + The psycopg connection object to be instrumented. + tracer_provider: opentelemetry.trace.TracerProvider, optional + The TracerProvider to use for instrumentation. If not provided, + the global TracerProvider will be used. + + Returns: + An instrumented psycopg connection object. + """ if not hasattr(connection, "_is_instrumented_by_opentelemetry"): connection._is_instrumented_by_opentelemetry = False diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py index de2e49f4c3..a811f4285a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py @@ -88,15 +88,31 @@ import psycopg2 from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor - + # Call instrument() to wrap all database connections Psycopg2Instrumentor().instrument() cnx = psycopg2.connect(database='Database') + cursor = cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() +.. code-block:: python + + import psycopg2 + from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor + + # Alternatively, use instrument_connection for an individual connection + cnx = psycopg2.connect(database='Database') + instrumented_cnx = Psycopg2Instrumentor().instrument_connection(cnx) + cursor = instrumented_cnx.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") + cursor.execute("INSERT INTO test (testField) VALUES (123)") + cursor.close() + instrumented_cnx.close() + API --- """ @@ -160,6 +176,19 @@ def _uninstrument(self, **kwargs): # TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql @staticmethod def instrument_connection(connection, tracer_provider=None): + """Enable instrumentation in a psycopg2 connection. + + Args: + connection: psycopg2.extensions.connection + The psycopg2 connection object to be instrumented. + tracer_provider: opentelemetry.trace.TracerProvider, optional + The TracerProvider to use for instrumentation. If not specified, + the global TracerProvider will be used. + + Returns: + An instrumented psycopg2 connection object. + """ + if not hasattr(connection, "_is_instrumented_by_opentelemetry"): connection._is_instrumented_by_opentelemetry = False diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py index eb4435813d..54c614f745 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py @@ -26,6 +26,7 @@ import pymysql from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor + # Call instrument() to wrap all database connections PyMySQLInstrumentor().instrument() cnx = pymysql.connect(database="MySQL_Database") @@ -35,6 +36,28 @@ cursor.close() cnx.close() + +.. code:: python + + import pymysql + from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor + + # Alternatively, use instrument_connection for an individual connection + cnx = pymysql.connect(database="MySQL_Database") + instrumented_cnx = PyMySQLInstrumentor().instrument_connection( + cnx, + enable_commenter=True, + commenter_options={ + "db_driver": True, + "mysql_client_version": True + } + ) + cursor = instrumented_cnx.cursor() + cursor.execute("INSERT INTO test (testField) VALUES (123)" + instrumented_cnx.commit() + cursor.close() + instrumented_cnx.close() + SQLCOMMENTER ***************************************** You can optionally configure PyMySQL instrumentation to enable sqlcommenter which enriches @@ -165,10 +188,20 @@ def instrument_connection( """Enable instrumentation in a PyMySQL connection. Args: - connection: The connection to instrument. - tracer_provider: The optional tracer provider to use. If omitted - the current globally configured one is used. - + connection: + The existing PyMySQL connection instance that needs to be instrumented. + This connection was typically created using `pymysql.connect()` and is wrapped with OpenTelemetry tracing. + tracer_provider: + An optional `TracerProvider` instance that specifies which tracer provider should be used. + If not provided, the globally configured OpenTelemetry tracer provider is automatically applied. + enable_commenter: + A flag to enable the SQL Commenter feature. If `True`, query logs will be enriched with additional + contextual metadata (e.g., database version, traceparent IDs, driver information). + commenter_options: + A dictionary containing configuration options for the SQL Commenter feature. + You can specify various options, such as enabling driver information, database version logging, + traceparent propagation, and other customizable metadata enhancements. + See *SQLCommenter Configurations* above for more information. Returns: An instrumented connection. """ diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py index ec4f8ecc50..086d47f3f5 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py @@ -27,16 +27,31 @@ import sqlite3 from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor - + # Call instrument() to wrap all database connections SQLite3Instrumentor().instrument() cnx = sqlite3.connect(':memory:') cursor = cnx.cursor() - cursor.execute("CREATE TABLE test (testField INTEGER)") + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") cursor.execute("INSERT INTO test (testField) VALUES (123)") cursor.close() cnx.close() +.. code:: python + + import sqlite3 + from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor + + # Alternatively, use instrument_connection for an individual connection + conn = sqlite3.connect(":memory:") + instrumented_connection = SQLite3Instrumentor().instrument_connection(conn) + cursor = instrumented_connection.cursor() + cursor.execute("CREATE TABLE IF NOT EXISTS test (testField INTEGER)") + cursor.execute("INSERT INTO test (testField) VALUES (123)") + cursor.execute("SELECT * FROM test") + cursor.close() + instrumented_connection.close() + API --- """ @@ -104,9 +119,10 @@ def instrument_connection( the current globally configured one is used. Returns: - An instrumented connection. - """ + An instrumented SQLite connection that supports + telemetry for tracing database operations. + """ return dbapi.instrument_connection( __name__, connection, diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py b/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py index 581920232b..b9fb1f10ec 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py @@ -29,6 +29,10 @@ def setUp(self): self._cursor = self._connection.cursor() self._connection2 = dbapi2.connect(":memory:") self._cursor2 = self._connection2.cursor() + self._connection3 = SQLite3Instrumentor.instrument_connection( + dbapi2.connect(":memory:") + ) + self._cursor3 = self._connection3.cursor() def tearDown(self): super().tearDown() @@ -40,6 +44,10 @@ def tearDown(self): self._cursor2.close() if self._connection2: self._connection2.close() + if self._cursor3: + self._cursor3.close() + if self._connection3: + self._connection3.close() SQLite3Instrumentor().uninstrument() def validate_spans(self, span_name): @@ -65,6 +73,7 @@ def _create_tables(self): stmt = "CREATE TABLE IF NOT EXISTS test (id integer)" self._cursor.execute(stmt) self._cursor2.execute(stmt) + self._cursor3.execute(stmt) self.memory_exporter.clear() def test_execute(self): @@ -78,6 +87,10 @@ def test_execute(self): self._cursor2.execute(stmt) self.validate_spans("CREATE") + with self._tracer.start_as_current_span("rootSpan"): + self._cursor3.execute(stmt) + self.validate_spans("CREATE") + def test_executemany(self): """Should create a child span for executemany""" self._create_tables() @@ -93,6 +106,10 @@ def test_executemany(self): self._cursor2.executemany(stmt, data) self.validate_spans("INSERT") + with self._tracer.start_as_current_span("rootSpan"): + self._cursor3.executemany(stmt, data) + self.validate_spans("INSERT") + def test_callproc(self): """Should create a child span for callproc""" with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( From 72576f65e0d77620c5696824146c0280a8ec1e4f Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Sat, 21 Dec 2024 18:45:53 -0500 Subject: [PATCH 288/335] Vertex AI instrumentation boilerplate (#3123) * Vertex AI boilerplate copied from openai-v2 * tox.ini boilerplate * tox -e generate,generate-workflows --- .github/workflows/core_contrib_test_0.yml | 44 +++ .github/workflows/lint_0.yml | 18 + .github/workflows/test_0.yml | 360 +++++++++--------- .github/workflows/test_1.yml | 360 +++++++++--------- .github/workflows/test_2.yml | 180 +++++++++ .../CHANGELOG.md | 11 + .../LICENSE | 201 ++++++++++ .../README.rst | 79 ++++ .../examples/manual/.env | 8 + .../examples/manual/README.rst | 43 +++ .../examples/manual/main.py | 47 +++ .../examples/manual/requirements.txt | 5 + .../examples/zero-code/.env | 13 + .../examples/zero-code/README.rst | 38 ++ .../examples/zero-code/main.py | 15 + .../examples/zero-code/requirements.txt | 6 + .../pyproject.toml | 50 +++ .../instrumentation/vertexai/__init__.py | 74 ++++ .../instrumentation/vertexai/package.py | 16 + .../instrumentation/vertexai/patch.py | 13 + .../instrumentation/vertexai/version.py | 15 + .../test-requirements-0.txt | 57 +++ .../test-requirements-1.txt | 54 +++ .../tests/__init__.py | 0 .../tests/conftest.py | 136 +++++++ .../tests/test_placeholder.py | 20 + .../instrumentation/bootstrap_gen.py | 4 + tox.ini | 14 + 28 files changed, 1521 insertions(+), 360 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/CHANGELOG.md create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/LICENSE create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/README.rst create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/.env create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/README.rst create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/main.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/requirements.txt create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/README.rst create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/main.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/requirements.txt create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/package.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/version.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-0.txt create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-1.txt create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/__init__.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_placeholder.py diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index 67bda629ff..aa5ca12b5e 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -63,6 +63,50 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-openai-v2-1 -- -ra + py38-test-instrumentation-vertexai-0: + name: instrumentation-vertexai-0 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-vertexai-0 -- -ra + + py38-test-instrumentation-vertexai-1: + name: instrumentation-vertexai-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-vertexai-1 -- -ra + py38-test-resource-detector-container: name: resource-detector-container runs-on: ubuntu-latest diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index 9d77ef5e27..80c7902e6b 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -34,6 +34,24 @@ jobs: - name: Run tests run: tox -e lint-instrumentation-openai-v2 + lint-instrumentation-vertexai: + name: instrumentation-vertexai + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e lint-instrumentation-vertexai + lint-resource-detector-container: name: resource-detector-container runs-on: ubuntu-latest diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index 47c9a19cf3..92352959e5 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -232,6 +232,186 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-openai-v2-1 -- -ra + py38-test-instrumentation-vertexai-0_ubuntu-latest: + name: instrumentation-vertexai-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-vertexai-0 -- -ra + + py38-test-instrumentation-vertexai-1_ubuntu-latest: + name: instrumentation-vertexai-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-vertexai-1 -- -ra + + py39-test-instrumentation-vertexai-0_ubuntu-latest: + name: instrumentation-vertexai-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-vertexai-0 -- -ra + + py39-test-instrumentation-vertexai-1_ubuntu-latest: + name: instrumentation-vertexai-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-vertexai-1 -- -ra + + py310-test-instrumentation-vertexai-0_ubuntu-latest: + name: instrumentation-vertexai-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-vertexai-0 -- -ra + + py310-test-instrumentation-vertexai-1_ubuntu-latest: + name: instrumentation-vertexai-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-vertexai-1 -- -ra + + py311-test-instrumentation-vertexai-0_ubuntu-latest: + name: instrumentation-vertexai-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-vertexai-0 -- -ra + + py311-test-instrumentation-vertexai-1_ubuntu-latest: + name: instrumentation-vertexai-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-vertexai-1 -- -ra + + py312-test-instrumentation-vertexai-0_ubuntu-latest: + name: instrumentation-vertexai-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-vertexai-0 -- -ra + + py312-test-instrumentation-vertexai-1_ubuntu-latest: + name: instrumentation-vertexai-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-vertexai-1 -- -ra + py38-test-resource-detector-container_ubuntu-latest: name: resource-detector-container 3.8 Ubuntu runs-on: ubuntu-latest @@ -4335,183 +4515,3 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-mysqlclient -- -ra - - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra - - py310-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-mysqlclient -- -ra - - py311-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-mysqlclient -- -ra - - py312-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-mysqlclient -- -ra - - pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - - py38-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-psycopg2 -- -ra - - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra - - py310-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2 -- -ra - - py311-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2 -- -ra - - py312-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 9c5d48aea3..e6aa293f9d 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,186 @@ env: jobs: + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-mysqlclient -- -ra + + py310-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-mysqlclient -- -ra + + py311-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-mysqlclient -- -ra + + py312-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-mysqlclient -- -ra + + pypy3-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra + + py38-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg2 -- -ra + + py39-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg2 -- -ra + + py310-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg2 -- -ra + + py311-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg2 -- -ra + + py312-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg2 -- -ra + py38-test-instrumentation-psycopg_ubuntu-latest: name: instrumentation-psycopg 3.8 Ubuntu runs-on: ubuntu-latest @@ -4335,183 +4515,3 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-asyncio -- -ra - - py38-test-instrumentation-cassandra_ubuntu-latest: - name: instrumentation-cassandra 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-cassandra -- -ra - - py39-test-instrumentation-cassandra_ubuntu-latest: - name: instrumentation-cassandra 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra -- -ra - - py310-test-instrumentation-cassandra_ubuntu-latest: - name: instrumentation-cassandra 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-cassandra -- -ra - - py311-test-instrumentation-cassandra_ubuntu-latest: - name: instrumentation-cassandra 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-cassandra -- -ra - - py312-test-instrumentation-cassandra_ubuntu-latest: - name: instrumentation-cassandra 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-cassandra -- -ra - - pypy3-test-instrumentation-cassandra_ubuntu-latest: - name: instrumentation-cassandra pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-cassandra -- -ra - - py38-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-processor-baggage -- -ra - - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra - - py310-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-processor-baggage -- -ra - - py311-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-processor-baggage -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index c23866ffa8..7614c8988f 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -16,6 +16,186 @@ env: jobs: + py38-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-cassandra -- -ra + + py39-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-cassandra -- -ra + + py310-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-cassandra -- -ra + + py311-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-cassandra -- -ra + + py312-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-cassandra -- -ra + + pypy3-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-cassandra -- -ra + + py38-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-processor-baggage -- -ra + + py39-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-processor-baggage -- -ra + + py310-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-processor-baggage -- -ra + + py311-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-processor-baggage -- -ra + py312-test-processor-baggage_ubuntu-latest: name: processor-baggage 3.12 Ubuntu runs-on: ubuntu-latest diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-vertexai/CHANGELOG.md new file mode 100644 index 0000000000..4d786c7840 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +- Initial VertexAI instrumentation + ([#3123](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3123)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/LICENSE b/instrumentation-genai/opentelemetry-instrumentation-vertexai/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/README.rst b/instrumentation-genai/opentelemetry-instrumentation-vertexai/README.rst new file mode 100644 index 0000000000..ecb404cb70 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/README.rst @@ -0,0 +1,79 @@ +OpenTelemetry VertexAI Instrumentation +==================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-vertexai.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-vertexai/ + +This library allows tracing LLM requests and logging of messages made by the +`VertexAI Python API library `_. + + +Installation +------------ + +If your application is already instrumented with OpenTelemetry, add this +package to your requirements. +:: + + pip install opentelemetry-instrumentation-vertexai + +If you don't have an VertexAI application, yet, try our `examples `_. + +Check out `zero-code example `_ for a quick start. + +Usage +----- + +This section describes how to set up VertexAI instrumentation if you're setting OpenTelemetry up manually. +Check out the `manual example `_ for more details. + +Instrumenting all clients +************************* + +When using the instrumentor, all clients will automatically trace VertexAI chat completion operations. +You can also optionally capture prompts and completions as log events. + +Make sure to configure OpenTelemetry tracing, logging, and events to capture all telemetry emitted by the instrumentation. + +.. code-block:: python + + from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor + from vertexai.generative_models import GenerativeModel + + VertexAIInstrumentor().instrument() + + + vertexai.init() + model = GenerativeModel("gemini-1.5-flash-002") + response = model.generate_content("Write a short poem on OpenTelemetry.") + +Enabling message content +************************* + +Message content such as the contents of the prompt, completion, function arguments and return values +are not captured by default. To capture message content as log events, set the environment variable +`OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` to `true`. + +Uninstrument +************ + +To uninstrument clients, call the uninstrument method: + +.. code-block:: python + + from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor + + VertexAIInstrumentor().instrument() + # ... + + # Uninstrument all clients + VertexAIInstrumentor().uninstrument() + +References +---------- +* `OpenTelemetry VertexAI Instrumentation `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ + diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/.env b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/.env new file mode 100644 index 0000000000..9ca033983f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/.env @@ -0,0 +1,8 @@ +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + +OTEL_SERVICE_NAME=opentelemetry-python-vertexai + +# Change to 'false' to hide prompt and completion content +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/README.rst b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/README.rst new file mode 100644 index 0000000000..ab5e7d1c5c --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/README.rst @@ -0,0 +1,43 @@ +OpenTelemetry VertexAI Instrumentation Example +============================================ + +This is an example of how to instrument VertexAI calls when configuring OpenTelemetry SDK and Instrumentations manually. + +When `main.py `_ is run, it exports traces and logs to an OTLP +compatible endpoint. Traces include details such as the model used and the +duration of the chat request. Logs capture the chat request and the generated +response, providing a comprehensive view of the performance and behavior of +your VertexAI requests. + +Note: `.env <.env>`_ file configures additional environment variables: + +- `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true` configures +VertexAI instrumentation to capture prompt and completion contents on +events. + +Setup +----- + +An OTLP compatible endpoint should be listening for traces and logs on +http://localhost:4317. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example like this: + +:: + + dotenv run -- python main.py + +You should see a poem generated by VertexAI while traces and logs export to your +configured observability tool. diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/main.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/main.py new file mode 100644 index 0000000000..5d329aad8b --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/main.py @@ -0,0 +1,47 @@ +# pylint: skip-file +import vertexai +from vertexai.generative_models import GenerativeModel + +# NOTE: OpenTelemetry Python Logs and Events APIs are in beta +from opentelemetry import _events, _logs, trace +from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( + OTLPLogExporter, +) +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter, +) +from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import BatchLogRecordProcessor +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +# configure tracing +trace.set_tracer_provider(TracerProvider()) +trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(OTLPSpanExporter()) +) + +# configure logging and events +_logs.set_logger_provider(LoggerProvider()) +_logs.get_logger_provider().add_log_record_processor( + BatchLogRecordProcessor(OTLPLogExporter()) +) +_events.set_event_logger_provider(EventLoggerProvider()) + +# instrument VertexAI +VertexAIInstrumentor().instrument() + + +def main(): + vertexai.init() + model = GenerativeModel("gemini-1.5-flash-002") + chat_completion = model.generate_content( + "Write a short poem on OpenTelemetry." + ) + print(chat_completion.text) + + +if __name__ == "__main__": + main() diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/requirements.txt new file mode 100644 index 0000000000..aa02037507 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/manual/requirements.txt @@ -0,0 +1,5 @@ +google-cloud-aiplatform>=1.64 + +opentelemetry-sdk~=1.29.0 +opentelemetry-exporter-otlp-proto-grpc~=1.29.0 +opentelemetry-instrumentation-vertexai~=2.0b0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env new file mode 100644 index 0000000000..8874bc5e29 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env @@ -0,0 +1,13 @@ +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + +OTEL_SERVICE_NAME=opentelemetry-python-vertexai + +# Change to 'false' to disable logging +OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true +# Change to 'console' if your OTLP endpoint doesn't support logs +# TODO: this should not be necessary once https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3042 is released +OTEL_LOGS_EXPORTER=otlp +# Change to 'false' to hide prompt and completion content +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/README.rst b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/README.rst new file mode 100644 index 0000000000..6fe161f82f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/README.rst @@ -0,0 +1,38 @@ +OpenTelemetry VertexAI Instrumentation Example +============================================ + +This is an example of how to instrument VertexAI calls with zero code changes, +using `opentelemetry-instrument`. + +When `main.py `_ is run, it exports traces and logs to an OTLP +compatible endpoint. Traces include details such as the model used and the +duration of the chat request. Logs capture the chat request and the generated +response, providing a comprehensive view of the performance and behavior of +your VertexAI requests. + +Setup +----- + +An OTLP compatible endpoint should be listening for traces and logs on http://localhost:4318. +If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example like this: + +:: + + dotenv run -- opentelemetry-instrument python main.py + +You should see a poem generated by VertexAI while traces and logs export to your +configured observability tool. diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/main.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/main.py new file mode 100644 index 0000000000..0f9086bb88 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/main.py @@ -0,0 +1,15 @@ +import vertexai +from vertexai.generative_models import GenerativeModel + + +def main(): + vertexai.init() + model = GenerativeModel("gemini-1.5-flash-002") + chat_completion = model.generate_content( + "Write a short poem on OpenTelemetry." + ) + print(chat_completion.text) + + +if __name__ == "__main__": + main() diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/requirements.txt new file mode 100644 index 0000000000..a44caf9766 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/requirements.txt @@ -0,0 +1,6 @@ +google-cloud-aiplatform>=1.64 + +opentelemetry-sdk~=1.28.2 +opentelemetry-exporter-otlp-proto-http~=1.28.2 +opentelemetry-distro~=0.49b2 +opentelemetry-instrumentation-vertexai~=2.0b0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml new file mode 100644 index 0000000000..910ebc2328 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -0,0 +1,50 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-vertexai" +dynamic = ["version"] +description = "OpenTelemetry Official VertexAI instrumentation" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.8" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "opentelemetry-api ~= 1.28", + "opentelemetry-instrumentation ~= 0.49b0", + "opentelemetry-semantic-conventions ~= 0.49b0", +] + +[project.optional-dependencies] +instruments = ["google-cloud-aiplatform >= 1.64"] + +[project.entry-points.opentelemetry_instrumentor] +vertexai = "opentelemetry.instrumentation.vertexai:VertexAIInstrumentor" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-vertexai" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/vertexai/version.py" + +[tool.hatch.build.targets.sdist] +include = ["/src", "/tests"] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py new file mode 100644 index 0000000000..b2011513a9 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py @@ -0,0 +1,74 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +VertexAI client instrumentation supporting `google-cloud-aiplatform` SDK, it can be enabled by +using ``VertexAIInstrumentor``. + +.. _vertexai: https://pypi.org/project/google-cloud-aiplatform/ + +Usage +----- + +.. code:: python + + import vertexai + from vertexai.generative_models import GenerativeModel + from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor + + VertexAIInstrumentor().instrument() + + vertexai.init() + model = GenerativeModel("gemini-1.5-flash-002") + chat_completion = model.generate_content( + "Write a short poem on OpenTelemetry." + ) + +API +--- +""" + +from typing import Collection + +from opentelemetry._events import get_event_logger +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.instrumentation.vertexai.package import _instruments +from opentelemetry.semconv.schemas import Schemas +from opentelemetry.trace import get_tracer + + +class VertexAIInstrumentor(BaseInstrumentor): + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs): + """Enable VertexAI instrumentation.""" + tracer_provider = kwargs.get("tracer_provider") + _tracer = get_tracer( + __name__, + "", + tracer_provider, + schema_url=Schemas.V1_28_0.value, + ) + event_logger_provider = kwargs.get("event_logger_provider") + _event_logger = get_event_logger( + __name__, + "", + schema_url=Schemas.V1_28_0.value, + event_logger_provider=event_logger_provider, + ) + # TODO: implemented in later PR + + def _uninstrument(self, **kwargs) -> None: + """TODO: implemented in later PR""" diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/package.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/package.py new file mode 100644 index 0000000000..c5f776ac5e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/package.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +_instruments = ("google-cloud-aiplatform >= 1.64",) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py new file mode 100644 index 0000000000..b0a6f42841 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py @@ -0,0 +1,13 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/version.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/version.py new file mode 100644 index 0000000000..5b77207d9d --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "2.1b0.dev" diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-0.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-0.txt new file mode 100644 index 0000000000..3450e980ad --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-0.txt @@ -0,0 +1,57 @@ +annotated-types==0.7.0 +cachetools==5.5.0 +certifi==2024.8.30 +charset-normalizer==3.4.0 +Deprecated==1.2.14 +docstring_parser==0.16 +exceptiongroup==1.2.2 +google-api-core==2.23.0 +google-auth==2.36.0 +google-cloud-aiplatform==1.74.0 +google-cloud-bigquery==3.27.0 +google-cloud-core==2.4.1 +google-cloud-resource-manager==1.13.1 +google-cloud-storage==2.19.0 +google-crc32c==1.5.0 +google-resumable-media==2.7.2 +googleapis-common-protos==1.66.0 +grpc-google-iam-v1==0.13.1 +grpcio==1.68.1 +grpcio-status==1.68.1 +idna==3.10 +importlib-metadata==6.11.0 +iniconfig==2.0.0 +multidict==6.1.0 +packaging==24.0 +pluggy==1.5.0 +propcache==0.2.0 +proto-plus==1.25.0 +protobuf==5.29.1 +pyasn1==0.6.1 +pyasn1_modules==0.4.1 +pydantic==2.8.2 +pydantic_core==2.20.1 +pytest==7.4.4 +pytest-asyncio==0.21.0 +pytest-vcr==1.0.2 +python-dateutil==2.9.0.post0 +PyYAML==6.0.2 +requests==2.32.3 +rsa==4.9 +shapely==2.0.6 +six==1.17.0 +tomli==2.2.1 +typing_extensions==4.12.2 +urllib3==1.26.20 +vcrpy==6.0.2 +wrapt==1.16.0 +yarl==1.15.2 +zipp==3.20.2 + +# when updating, also update in pyproject.toml +opentelemetry-api==1.28 +opentelemetry-sdk==1.28 +opentelemetry-semantic-conventions==0.49b0 +opentelemetry-instrumentation==0.49b0 + +-e instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-1.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-1.txt new file mode 100644 index 0000000000..9980561fb5 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-1.txt @@ -0,0 +1,54 @@ +annotated-types==0.7.0 +asgiref==3.8.1 +cachetools==5.5.0 +certifi==2024.8.30 +charset-normalizer==3.4.0 +Deprecated==1.2.15 +docstring_parser==0.16 +exceptiongroup==1.2.2 +google-api-core==2.23.0 +google-auth==2.36.0 +google-cloud-aiplatform==1.74.0 +google-cloud-bigquery==3.27.0 +google-cloud-core==2.4.1 +google-cloud-resource-manager==1.13.1 +google-cloud-storage==2.19.0 +google-crc32c==1.5.0 +google-resumable-media==2.7.2 +googleapis-common-protos==1.66.0 +grpc-google-iam-v1==0.13.1 +grpcio==1.68.1 +grpcio-status==1.68.1 +idna==3.10 +importlib_metadata==8.5.0 +iniconfig==2.0.0 +multidict==6.1.0 +packaging==24.2 +pluggy==1.5.0 +propcache==0.2.0 +proto-plus==1.25.0 +protobuf==5.29.1 +pyasn1==0.6.1 +pyasn1_modules==0.4.1 +pydantic==2.10.3 +pydantic_core==2.27.1 +pytest==7.4.4 +pytest-asyncio==0.21.0 +pytest-vcr==1.0.2 +python-dateutil==2.9.0.post0 +PyYAML==6.0.2 +requests==2.32.3 +rsa==4.9 +shapely==2.0.6 +six==1.17.0 +tomli==2.2.1 +typing_extensions==4.12.2 +urllib3==1.26.20 +vcrpy==6.0.2 +wrapt==1.17.0 +yarl==1.15.2 +zipp==3.20.2 +# test with the latest version of opentelemetry-api, sdk, and semantic conventions + +-e opentelemetry-instrumentation +-e instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py new file mode 100644 index 0000000000..8337188ece --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py @@ -0,0 +1,136 @@ +"""Unit tests configuration module.""" + +import json + +import pytest +import yaml + +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, + SimpleLogRecordProcessor, +) +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + + +@pytest.fixture(scope="function", name="span_exporter") +def fixture_span_exporter(): + exporter = InMemorySpanExporter() + yield exporter + + +@pytest.fixture(scope="function", name="log_exporter") +def fixture_log_exporter(): + exporter = InMemoryLogExporter() + yield exporter + + +@pytest.fixture(scope="function", name="tracer_provider") +def fixture_tracer_provider(span_exporter): + provider = TracerProvider() + provider.add_span_processor(SimpleSpanProcessor(span_exporter)) + return provider + + +@pytest.fixture(scope="function", name="event_logger_provider") +def fixture_event_logger_provider(log_exporter): + provider = LoggerProvider() + provider.add_log_record_processor(SimpleLogRecordProcessor(log_exporter)) + event_logger_provider = EventLoggerProvider(provider) + + return event_logger_provider + + +@pytest.fixture(scope="module") +def vcr_config(): + return { + "filter_headers": [ + ("cookie", "test_cookie"), + ("authorization", "Bearer test_vertexai_api_key"), + ("vertexai-organization", "test_vertexai_org_id"), + ("vertexai-project", "test_vertexai_project_id"), + ], + "decode_compressed_response": True, + "before_record_response": scrub_response_headers, + } + + +class LiteralBlockScalar(str): + """Formats the string as a literal block scalar, preserving whitespace and + without interpreting escape characters""" + + +def literal_block_scalar_presenter(dumper, data): + """Represents a scalar string as a literal block, via '|' syntax""" + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|") + + +yaml.add_representer(LiteralBlockScalar, literal_block_scalar_presenter) + + +def process_string_value(string_value): + """Pretty-prints JSON or returns long strings as a LiteralBlockScalar""" + try: + json_data = json.loads(string_value) + return LiteralBlockScalar(json.dumps(json_data, indent=2)) + except (ValueError, TypeError): + if len(string_value) > 80: + return LiteralBlockScalar(string_value) + return string_value + + +def convert_body_to_literal(data): + """Searches the data for body strings, attempting to pretty-print JSON""" + if isinstance(data, dict): + for key, value in data.items(): + # Handle response body case (e.g., response.body.string) + if key == "body" and isinstance(value, dict) and "string" in value: + value["string"] = process_string_value(value["string"]) + + # Handle request body case (e.g., request.body) + elif key == "body" and isinstance(value, str): + data[key] = process_string_value(value) + + else: + convert_body_to_literal(value) + + elif isinstance(data, list): + for idx, choice in enumerate(data): + data[idx] = convert_body_to_literal(choice) + + return data + + +class PrettyPrintJSONBody: + """This makes request and response body recordings more readable.""" + + @staticmethod + def serialize(cassette_dict): + cassette_dict = convert_body_to_literal(cassette_dict) + return yaml.dump( + cassette_dict, default_flow_style=False, allow_unicode=True + ) + + @staticmethod + def deserialize(cassette_string): + return yaml.load(cassette_string, Loader=yaml.Loader) + + +@pytest.fixture(scope="module", autouse=True) +def fixture_vcr(vcr): + vcr.register_serializer("yaml", PrettyPrintJSONBody) + return vcr + + +def scrub_response_headers(response): + """ + This scrubs sensitive response headers. Note they are case-sensitive! + """ + response["headers"]["vertexai-organization"] = "test_vertexai_org_id" + response["headers"]["Set-Cookie"] = "test_set_cookie" + return response diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_placeholder.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_placeholder.py new file mode 100644 index 0000000000..c910bfa0bf --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_placeholder.py @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# TODO: adapt tests from OpenLLMetry here along with tests from +# instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py + + +def test_placeholder(): + assert True diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 4e497b8208..5825e8f7b8 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -20,6 +20,10 @@ "library": "openai >= 1.26.0", "instrumentation": "opentelemetry-instrumentation-openai-v2==2.1b0.dev", }, + { + "library": "google-cloud-aiplatform >= 1.64", + "instrumentation": "opentelemetry-instrumentation-vertexai==2.1b0.dev", + }, { "library": "aio_pika >= 7.2.0, < 10.0.0", "instrumentation": "opentelemetry-instrumentation-aio-pika==0.51b0.dev", diff --git a/tox.ini b/tox.ini index 563f6cc34d..369ccaaf76 100644 --- a/tox.ini +++ b/tox.ini @@ -11,6 +11,12 @@ envlist = pypy3-test-instrumentation-openai-v2-{0,1} lint-instrumentation-openai-v2 + ; instrumentation-vertexai + py3{8,9,10,11,12}-test-instrumentation-vertexai-{0,1} + # Disabling pypy3 as shapely does not have wheels and fails to compile + # pypy3-test-instrumentation-vertexai-{0,1} + lint-instrumentation-vertexai + ; opentelemetry-resource-detector-container py3{8,9,10,11,12}-test-resource-detector-container pypy3-test-resource-detector-container @@ -418,6 +424,11 @@ deps = openai-1: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt lint-instrumentation-openai-v2: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt + vertexai-0: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-0.txt + vertexai-1: {[testenv]test_deps} + vertexai-1: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-1.txt + lint-instrumentation-vertexai: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-vertexai/test-requirements-0.txt + asgi: {[testenv]test_deps} asgi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -769,6 +780,9 @@ commands = test-instrumentation-openai-v2: pytest {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests {posargs} lint-instrumentation-openai-v2: sh -c "cd instrumentation-genai && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-openai-v2" + test-instrumentation-vertexai: pytest {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests {posargs} + lint-instrumentation-vertexai: sh -c "cd instrumentation-genai && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-vertexai" + test-instrumentation-sio-pika: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/tests {posargs} lint-instrumentation-sio-pika: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pika" From 7eead8f1aec5d3e5086aeaa2782968fc8e74cf40 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 23 Dec 2024 10:43:09 +0100 Subject: [PATCH 289/335] opentelemetry-sdk-extension-aws: make ec2 resource detector silent when loaded outside AWS (#3120) * opentelemetry-sdk-extension-aws: make ec2 resource detector silent when loaded outside AWS Assume that if we fail to get the token quickly we are not on AWS. --- .../CHANGELOG.md | 2 ++ .../sdk/extension/aws/resource/ec2.py | 33 +++++++++++++++---- .../tests/resource/test_ec2.py | 20 +++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md index c1c8286894..25201d51d1 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md +++ b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Make ec2 resource detector silent when loaded outside AWS + ([#3120](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3120)) - Make ecs and beanstalk resource detector silent when loaded outside AWS ([#3076](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3076)) - Make EKS resource detector don't warn when not running in EKS diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py index b0cfeeb312..cc497264f5 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py @@ -14,6 +14,7 @@ import json import logging +from urllib.error import URLError from urllib.request import Request, urlopen from opentelemetry.sdk.resources import Resource, ResourceDetector @@ -27,39 +28,47 @@ _AWS_METADATA_TOKEN_HEADER = "X-aws-ec2-metadata-token" _GET_METHOD = "GET" +_AWS_METADATA_HOST = "169.254.169.254" -def _aws_http_request(method, path, headers): +def _aws_http_request(method, path, headers, timeout=None): + if timeout is None: + timeout = 5 with urlopen( Request( - "http://169.254.169.254" + path, headers=headers, method=method + "http://" + _AWS_METADATA_HOST + path, + headers=headers, + method=method, ), - timeout=5, + timeout=timeout, ) as response: return response.read().decode("utf-8") -def _get_token(): +def _get_token(timeout=None): return _aws_http_request( "PUT", "/latest/api/token", {"X-aws-ec2-metadata-token-ttl-seconds": "60"}, + timeout, ) -def _get_identity(token): +def _get_identity(token, timeout=None): return _aws_http_request( _GET_METHOD, "/latest/dynamic/instance-identity/document", {_AWS_METADATA_TOKEN_HEADER: token}, + timeout, ) -def _get_host(token): +def _get_host(token, timeout=None): return _aws_http_request( _GET_METHOD, "/latest/meta-data/hostname", {_AWS_METADATA_TOKEN_HEADER: token}, + timeout, ) @@ -72,7 +81,17 @@ class AwsEc2ResourceDetector(ResourceDetector): def detect(self) -> "Resource": try: - token = _get_token() + # If can't get a token quick assume we are not on ec2 + try: + token = _get_token(timeout=1) + except URLError as exception: + logger.debug( + "%s failed to get token: %s", + self.__class__.__name__, + exception, + ) + return Resource.get_empty() + identity_dict = json.loads(_get_identity(token)) hostname = _get_host(token) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py index 300f963ac5..88815ed55b 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py @@ -15,6 +15,7 @@ import unittest from collections import OrderedDict from unittest.mock import patch +from urllib.error import URLError from opentelemetry.sdk.extension.aws.resource.ec2 import ( # pylint: disable=no-name-in-module AwsEc2ResourceDetector, @@ -73,3 +74,22 @@ def test_simple_create( self.assertDictEqual( actual.attributes.copy(), OrderedDict(MockEc2ResourceAttributes) ) + + @patch( + "opentelemetry.sdk.extension.aws.resource.ec2._get_token", + side_effect=URLError("Something went wrong"), + ) + def test_empty_resource_if_token_returns_an_url_error( + self, mock_get_token + ): + with self.assertLogs( + "opentelemetry.sdk.extension.aws.resource.ec2", level="DEBUG" + ) as logger: + actual = AwsEc2ResourceDetector().detect() + self.assertEqual( + logger.output, + [ + "DEBUG:opentelemetry.sdk.extension.aws.resource.ec2:AwsEc2ResourceDetector failed to get token: " + ], + ) + self.assertDictEqual(actual.attributes.copy(), OrderedDict()) From 73ecf39517c4e1f6e62cfc0e6c8957e0765f2ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 23 Dec 2024 07:09:27 -0300 Subject: [PATCH 290/335] sqlalchemy: bump greenlet version in test requirements and use last requirement file for lint (#3139) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .../test-requirements-1.txt | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index 885cee8c62..13ea334c4d 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -1,7 +1,7 @@ aiosqlite==0.20.0 asgiref==3.8.1 Deprecated==1.2.14 -greenlet==3.0.3 +greenlet==3.1.1 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/tox.ini b/tox.ini index 369ccaaf76..eddd6c61ea 100644 --- a/tox.ini +++ b/tox.ini @@ -613,7 +613,7 @@ deps = sqlalchemy-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt sqlalchemy-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt sqlalchemy-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt - lint-instrumentation-sqlalchemy: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt + lint-instrumentation-sqlalchemy: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt elasticsearch: {[testenv]test_deps} elasticsearch-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt From 77708cd7dd199f2cf795382adfa16b8b78753676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:36:12 -0300 Subject: [PATCH 291/335] grpc: bump grpcio version in test-requirements (#3140) * grpc: bump grpcio version in test-requirements Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * keep 1.62.0 test Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix toxini Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .../opentelemetry-instrumentation-grpc/test-requirements-1.txt | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index 7618e99dfa..278f27cb9f 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -1,6 +1,6 @@ asgiref==3.8.1 Deprecated==1.2.14 -grpcio==1.63.0 +grpcio==1.66.2 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 diff --git a/tox.ini b/tox.ini index eddd6c61ea..9d79a11f8b 100644 --- a/tox.ini +++ b/tox.ini @@ -265,7 +265,7 @@ envlist = ; The numbers at the end of the environment names ; below mean these dependencies are being used: ; 0: grpcio==1.62.0 - ; 1: grpcio==1.63.0 + ; 1: grpcio==1.66.2 py3{8,9,10,11,12}-test-instrumentation-grpc-{0,1} lint-instrumentation-grpc From 59894979ef6dc7c57850d334a0dde61efdd616d1 Mon Sep 17 00:00:00 2001 From: Guangya Liu Date: Mon, 23 Dec 2024 09:02:02 -0500 Subject: [PATCH 292/335] [chore] Removed $ from command for contribution guidance (#3114) The copy in markdown file always copy the $ as well when copying the command, I need to remove the $ manually each time. Co-authored-by: Leighton Chen Co-authored-by: Riccardo Magliocchetti --- CONTRIBUTING.md | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ab22d3821f..8119304875 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,7 +56,7 @@ some aspects of development, including testing against multiple Python versions. To install `tox`, run: ```sh -$ pip install tox +pip install tox ``` You can run `tox` with the following arguments: @@ -74,13 +74,13 @@ You can run `tox` with the following arguments: `ruff check` and `ruff format` are executed when `tox -e ruff` is run. We strongly recommend you to configure [pre-commit](https://pre-commit.com/) locally to run `ruff` automatically before each commit by installing it as git hooks. You just need to [install pre-commit](https://pre-commit.com/#install) in your environment: ```console -$ pip install pre-commit -c dev-requirements.txt +pip install pre-commit -c dev-requirements.txt ``` and run this command inside the git repository: ```console -$ pre-commit install +pre-commit install ``` See @@ -126,31 +126,45 @@ pull requests (PRs). To create a new PR, fork the project in GitHub and clone the upstream repo: ```sh -$ git clone https://github.com/open-telemetry/opentelemetry-python-contrib.git -$ cd opentelemetry-python-contrib +git clone https://github.com/open-telemetry/opentelemetry-python-contrib.git +cd opentelemetry-python-contrib ``` Add your fork as an origin: ```sh -$ git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-python-contrib.git +git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-python-contrib.git ``` -Run tests: +make sure you have all supported versions of Python installed, install `tox` only for the first time: ```sh -# make sure you have all supported versions of Python installed -$ pip install tox # only first time. -$ tox # execute in the root of the repository +pip install tox +``` + +Run tests in the root of the repository (this will run all tox environments and may take some time): + +```sh +tox ``` Check out a new branch, make modifications and push the branch to your fork: ```sh -$ git checkout -b feature -# edit files -$ git commit -$ git push fork feature +git checkout -b feature +``` + +After you edit the files, stage changes in the current directory: + +```sh +git add . +``` + +Then run the following to commit the changes: + +```sh +git commit +git push fork feature ``` Open a pull request against the main `opentelemetry-python-contrib` repo. From 2176e3e43e6b01933c2cc3819a0dfddb94f334b7 Mon Sep 17 00:00:00 2001 From: YR Chen Date: Tue, 24 Dec 2024 01:34:48 +0800 Subject: [PATCH 293/335] opentelemetry-instrumentation-falcon: expand supported version to v4 (#3086) * opentelemetry-instrumentation-falcon: expand supported version to v4 Falcon v4 has a mostly identical interface to v3, and is proved to be fully compatible with `opentelemetry-instrumentation-falcon`. Loose the version check to `<5.0.0` to avoid false `DependencyConflict` alarm. * opentelemetry-instrumentation-falcon: generate tests for v4 * opentelemetry-instrumentation-falcon: prepare tests for v4 * opentelemetry-instrumentation-falcon: add test preset for `~=3.1.2` * docs: add changelog for Falcon v4 instrumentation * opentelemetry-instrumentation-falcon: adjust pylint mark for v4 * _has_fixed_http_target property Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * move changelog to the correct section Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix test and bootstrap_gen Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/core_contrib_test_0.yml | 22 ++ .github/workflows/test_0.yml | 360 +++++++++--------- .github/workflows/test_1.yml | 360 +++++++++--------- .github/workflows/test_2.yml | 180 +++++++++ CHANGELOG.md | 3 + instrumentation/README.md | 2 +- .../pyproject.toml | 2 +- .../instrumentation/falcon/__init__.py | 2 +- .../instrumentation/falcon/package.py | 2 +- .../test-requirements-3.txt | 16 + .../test-requirements-4.txt | 16 + .../tests/app.py | 12 +- .../tests/test_falcon.py | 37 +- .../instrumentation/bootstrap_gen.py | 2 +- tox.ini | 15 +- 15 files changed, 647 insertions(+), 384 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt create mode 100644 instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index aa5ca12b5e..6c0616e0a6 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -657,6 +657,28 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-falcon-2 -- -ra + py38-test-instrumentation-falcon-3: + name: instrumentation-falcon-3 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-3 -- -ra + py38-test-instrumentation-fastapi: name: instrumentation-fastapi runs-on: ubuntu-latest diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index 92352959e5..a0f561010e 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -2698,6 +2698,24 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-falcon-2 -- -ra + py38-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-falcon-3 -- -ra + py39-test-instrumentation-falcon-0_ubuntu-latest: name: instrumentation-falcon-0 3.9 Ubuntu runs-on: ubuntu-latest @@ -2752,6 +2770,24 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-falcon-2 -- -ra + py39-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-3 -- -ra + py310-test-instrumentation-falcon-1_ubuntu-latest: name: instrumentation-falcon-1 3.10 Ubuntu runs-on: ubuntu-latest @@ -2788,6 +2824,42 @@ jobs: - name: Run tests run: tox -e py310-test-instrumentation-falcon-2 -- -ra + py310-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-3 -- -ra + + py310-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-4 -- -ra + py311-test-instrumentation-falcon-1_ubuntu-latest: name: instrumentation-falcon-1 3.11 Ubuntu runs-on: ubuntu-latest @@ -2824,6 +2896,42 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-falcon-2 -- -ra + py311-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-3 -- -ra + + py311-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-4 -- -ra + py312-test-instrumentation-falcon-1_ubuntu-latest: name: instrumentation-falcon-1 3.12 Ubuntu runs-on: ubuntu-latest @@ -2860,6 +2968,42 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-falcon-2 -- -ra + py312-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-3 -- -ra + + py312-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-4 -- -ra + pypy3-test-instrumentation-falcon-0_ubuntu-latest: name: instrumentation-falcon-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -2914,6 +3058,42 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra + pypy3-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra + + pypy3-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra + py38-test-instrumentation-fastapi_ubuntu-latest: name: instrumentation-fastapi 3.8 Ubuntu runs-on: ubuntu-latest @@ -4335,183 +4515,3 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-mysql-0 -- -ra - - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra - - py310-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-mysql-0 -- -ra - - py310-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-mysql-1 -- -ra - - py311-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-mysql-0 -- -ra - - py311-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-mysql-1 -- -ra - - py312-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-mysql-0 -- -ra - - py312-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-mysql-1 -- -ra - - pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra - - pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - - py38-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-mysqlclient -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index e6aa293f9d..2fce71b031 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,186 @@ env: jobs: + py39-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-mysql-1 -- -ra + + py310-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-mysql-0 -- -ra + + py310-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-mysql-1 -- -ra + + py311-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-mysql-0 -- -ra + + py311-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-mysql-1 -- -ra + + py312-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-mysql-0 -- -ra + + py312-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-mysql-1 -- -ra + + pypy3-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra + + pypy3-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + + py38-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-mysqlclient -- -ra + py39-test-instrumentation-mysqlclient_ubuntu-latest: name: instrumentation-mysqlclient 3.9 Ubuntu runs-on: ubuntu-latest @@ -4335,183 +4515,3 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra - - py38-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-confluent-kafka -- -ra - - py39-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra - - py310-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-confluent-kafka -- -ra - - py311-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-confluent-kafka -- -ra - - py312-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-confluent-kafka -- -ra - - py38-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-asyncio -- -ra - - py39-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra - - py310-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-asyncio -- -ra - - py311-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-asyncio -- -ra - - py312-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-asyncio -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index 7614c8988f..b165817249 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -16,6 +16,186 @@ env: jobs: + py38-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-confluent-kafka -- -ra + + py39-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-confluent-kafka -- -ra + + py310-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-confluent-kafka -- -ra + + py311-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-confluent-kafka -- -ra + + py312-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-confluent-kafka -- -ra + + py38-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-asyncio -- -ra + + py39-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncio -- -ra + + py310-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncio -- -ra + + py311-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncio -- -ra + + py312-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncio -- -ra + py38-test-instrumentation-cassandra_ubuntu-latest: name: instrumentation-cassandra 3.8 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index a243091b1d..d17c18687c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) +- `opentelemetry-instrumentation-falcon` add support version to v4 + ([#3086](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3086)) + ### Fixed diff --git a/instrumentation/README.md b/instrumentation/README.md index b12ac1aa21..d1b383d5a6 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -20,7 +20,7 @@ | [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | experimental | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental -| [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 4.0.0 | Yes | experimental +| [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 5.0.0 | Yes | experimental | [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio >= 1.42.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 883c76a9fd..a2ccb77998 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -35,7 +35,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "falcon >= 1.4.1, < 3.1.2", + "falcon >= 1.4.1, < 5.0.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 28b394eaf0..1037f98f5f 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -542,7 +542,7 @@ def _remove_instrumented_middleware(self, app): for x in app._middlewares_list if not isinstance(x, _TraceMiddleware) ] - # pylint: disable=c-extension-no-member + # pylint: disable=no-member app._middleware = falcon.api_helpers.prepare_middleware( app._middlewares_list, independent_middleware=app._independent_middleware, diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py index 2fd463739c..440a6e25f2 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py @@ -13,6 +13,6 @@ # limitations under the License. -_instruments = ("falcon >= 1.4.1, < 4.0.0",) +_instruments = ("falcon >= 1.4.1, < 5.0.0",) _supports_metrics = True diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt new file mode 100644 index 0000000000..392a1ce385 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt @@ -0,0 +1,16 @@ +asgiref==3.8.1 +Deprecated==1.2.14 +falcon==3.1.3 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +tomli==2.0.1 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-wsgi +-e util/opentelemetry-util-http +-e instrumentation/opentelemetry-instrumentation-falcon diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt new file mode 100644 index 0000000000..0fd061b29a --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt @@ -0,0 +1,16 @@ +asgiref==3.8.1 +Deprecated==1.2.14 +falcon==4.0.2 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pytest==7.4.4 +tomli==2.0.1 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-wsgi +-e util/opentelemetry-util-http +-e instrumentation/opentelemetry-instrumentation-falcon diff --git a/instrumentation/opentelemetry-instrumentation-falcon/tests/app.py b/instrumentation/opentelemetry-instrumentation-falcon/tests/app.py index a4d279149d..416ac80dff 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/tests/app.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/tests/app.py @@ -4,12 +4,14 @@ # pylint:disable=R0201,W0613,E0602 +_parsed_falcon_version = package_version.parse(falcon.__version__) + + class HelloWorldResource: def _handle_request(self, _, resp): # pylint: disable=no-member resp.status = falcon.HTTP_201 - _parsed_falcon_version = package_version.parse(falcon.__version__) if _parsed_falcon_version < package_version.parse("3.0.0"): # Falcon 1 and Falcon 2 resp.body = "Hello World" @@ -65,11 +67,15 @@ class UserResource: def on_get(self, req, resp, user_id): # pylint: disable=no-member resp.status = falcon.HTTP_200 - resp.body = f"Hello user {user_id}" + + if _parsed_falcon_version < package_version.parse("3.0.0"): + # Falcon 1 and Falcon 2 + resp.body = f"Hello user {user_id}" + else: + resp.text = f"Hello user {user_id}" def make_app(): - _parsed_falcon_version = package_version.parse(falcon.__version__) if _parsed_falcon_version < package_version.parse("3.0.0"): # Falcon 1 and Falcon 2 app = falcon.API() diff --git a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py index dbc2512ca0..f940deb34e 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py @@ -57,6 +57,8 @@ "http.server.duration": _server_duration_attrs_old, } +_parsed_falcon_version = package_version.parse(_falcon_version) + class TestFalconBase(TestBase): def setUp(self): @@ -76,6 +78,13 @@ def setUp(self): ) self.app = make_app() + @property + def _has_fixed_http_target(self): + # In falcon<3.1.2, HTTP_TARGET is always set to / in TestClient + # In falcon>=3.1.2, HTTP_TARGET is set to unencoded path by default + # https://github.com/falconry/falcon/blob/69cdcd6edd2ee33f4ac9f7793e1cc3c4f99da692/falcon/testing/helpers.py#L1153-1156 # noqa + return _parsed_falcon_version < package_version.parse("3.1.2") + def client(self): return testing.TestClient(self.app) @@ -124,7 +133,9 @@ def _test_method(self, method): SpanAttributes.HTTP_SCHEME: "http", SpanAttributes.NET_HOST_PORT: 80, SpanAttributes.HTTP_HOST: "falconframework.org", - SpanAttributes.HTTP_TARGET: "/", + SpanAttributes.HTTP_TARGET: "/" + if self._has_fixed_http_target + else "/hello", SpanAttributes.NET_PEER_PORT: 65133, SpanAttributes.HTTP_FLAVOR: "1.1", "falcon.resource": "HelloWorldResource", @@ -132,7 +143,7 @@ def _test_method(self, method): }, ) # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1 - # In falcon>3, NET_PEER_IP is not set to anything by default to + # In falcon>=3, NET_PEER_IP is not set to anything by default # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa if SpanAttributes.NET_PEER_IP in span.attributes: self.assertEqual( @@ -155,14 +166,16 @@ def test_404(self): SpanAttributes.HTTP_SCHEME: "http", SpanAttributes.NET_HOST_PORT: 80, SpanAttributes.HTTP_HOST: "falconframework.org", - SpanAttributes.HTTP_TARGET: "/", + SpanAttributes.HTTP_TARGET: "/" + if self._has_fixed_http_target + else "/does-not-exist", SpanAttributes.NET_PEER_PORT: 65133, SpanAttributes.HTTP_FLAVOR: "1.1", SpanAttributes.HTTP_STATUS_CODE: 404, }, ) # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1 - # In falcon>3, NET_PEER_IP is not set to anything by default to + # In falcon>=3, NET_PEER_IP is not set to anything by default # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa if SpanAttributes.NET_PEER_IP in span.attributes: self.assertEqual( @@ -192,14 +205,16 @@ def test_500(self): SpanAttributes.HTTP_SCHEME: "http", SpanAttributes.NET_HOST_PORT: 80, SpanAttributes.HTTP_HOST: "falconframework.org", - SpanAttributes.HTTP_TARGET: "/", + SpanAttributes.HTTP_TARGET: "/" + if self._has_fixed_http_target + else "/error", SpanAttributes.NET_PEER_PORT: 65133, SpanAttributes.HTTP_FLAVOR: "1.1", SpanAttributes.HTTP_STATUS_CODE: 500, }, ) # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1 - # In falcon>3, NET_PEER_IP is not set to anything by default to + # In falcon>=3, NET_PEER_IP is not set to anything by default # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa if SpanAttributes.NET_PEER_IP in span.attributes: self.assertEqual( @@ -225,7 +240,9 @@ def test_url_template(self): SpanAttributes.HTTP_SCHEME: "http", SpanAttributes.NET_HOST_PORT: 80, SpanAttributes.HTTP_HOST: "falconframework.org", - SpanAttributes.HTTP_TARGET: "/", + SpanAttributes.HTTP_TARGET: "/" + if self._has_fixed_http_target + else "/user/123", SpanAttributes.NET_PEER_PORT: 65133, SpanAttributes.HTTP_FLAVOR: "1.1", "falcon.resource": "UserResource", @@ -524,8 +541,7 @@ def test_custom_request_header_not_added_in_internal_span(self): self.assertNotIn(key, span.attributes) @pytest.mark.skipif( - condition=package_version.parse(_falcon_version) - < package_version.parse("2.0.0"), + condition=_parsed_falcon_version < package_version.parse("2.0.0"), reason="falcon<2 does not implement custom response headers", ) def test_custom_response_header_added_in_server_span(self): @@ -559,8 +575,7 @@ def test_custom_response_header_added_in_server_span(self): self.assertNotIn(key, span.attributes) @pytest.mark.skipif( - condition=package_version.parse(_falcon_version) - < package_version.parse("2.0.0"), + condition=_parsed_falcon_version < package_version.parse("2.0.0"), reason="falcon<2 does not implement custom response headers", ) def test_custom_response_header_not_added_in_internal_span(self): diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 5825e8f7b8..a55f0ccd8e 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -93,7 +93,7 @@ "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.51b0.dev", }, { - "library": "falcon >= 1.4.1, < 3.1.2", + "library": "falcon >= 1.4.1, < 5.0.0", "instrumentation": "opentelemetry-instrumentation-falcon==0.51b0.dev", }, { diff --git a/tox.ini b/tox.ini index 9d79a11f8b..6c6abe3d42 100644 --- a/tox.ini +++ b/tox.ini @@ -117,14 +117,17 @@ envlist = ; opentelemetry-instrumentation-falcon ; py310 does not work with falcon 1 + ; py3{8,9} will be dropped for falcon 4 ; The numbers at the end of the environment names ; below mean these dependencies are being used: ; 0: falcon ==1.4.1 ; 1: falcon >=2.0.0,<3.0.0 - ; 2: falcon >=3.0.0,<4.0.0 - py3{8,9}-test-instrumentation-falcon-{0,1,2} - py3{10,11,12}-test-instrumentation-falcon-{1,2} - pypy3-test-instrumentation-falcon-{0,1,2} + ; 2: falcon >=3.0.0,<3.1.2 + ; 3: falcon >=3.1.2,<4.0.0 + ; 4: falcon >=4.0.0,<5.0.0 + py3{8,9}-test-instrumentation-falcon-{0,1,2,3} + py3{10,11,12}-test-instrumentation-falcon-{1,2,3,4} + pypy3-test-instrumentation-falcon-{0,1,2,3,4} lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi @@ -489,7 +492,9 @@ deps = falcon-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt falcon-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt falcon-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt - lint-instrumentation-falcon: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt + falcon-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt + falcon-4: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt + lint-instrumentation-falcon: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt flask: {[testenv]test_deps} flask-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt From b03bf0037fa557852b6b63bc5e542ad2af743472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 23 Dec 2024 14:47:09 -0300 Subject: [PATCH 294/335] asyncpg: bump version in test-requirements (#3146) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .../opentelemetry-instrumentation-asyncpg/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index c1a45c5887..b2b4401d6b 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -1,6 +1,6 @@ asgiref==3.8.1 async-timeout==4.0.3 -asyncpg==0.29.0 +asyncpg==0.30.0 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 From 5fd648eac49350f4522df36c940b2d8f50c691c3 Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Mon, 23 Dec 2024 14:29:50 -0500 Subject: [PATCH 295/335] Remove unnecessary configuration of logs exporter in Gen AI samples (#3141) It is no longer necessary since we now set up the logging pipeline by default with OTLP exporter. --- .../examples/zero-code/.env | 9 +++++---- .../examples/zero-code/.env | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env index 7dfa745e3b..8f2dd62b91 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/.env @@ -12,10 +12,11 @@ OPENAI_API_KEY=sk-YOUR_API_KEY OTEL_SERVICE_NAME=opentelemetry-python-openai -# Change to 'false' to disable logging +# Change to 'false' to disable collection of python logging logs OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true -# Change to 'console' if your OTLP endpoint doesn't support logs -# TODO: this should not be necessary once https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3042 is released -OTEL_LOGS_EXPORTER=otlp + +# Uncomment if your OTLP endpoint doesn't support logs +# OTEL_LOGS_EXPORTER=console + # Change to 'false' to hide prompt and completion content OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env index 8874bc5e29..eefbd59500 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/zero-code/.env @@ -4,10 +4,11 @@ OTEL_SERVICE_NAME=opentelemetry-python-vertexai -# Change to 'false' to disable logging +# Change to 'false' to disable collection of python logging logs OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true -# Change to 'console' if your OTLP endpoint doesn't support logs -# TODO: this should not be necessary once https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3042 is released -OTEL_LOGS_EXPORTER=otlp + +# Uncomment if your OTLP endpoint doesn't support logs +# OTEL_LOGS_EXPORTER=console + # Change to 'false' to hide prompt and completion content OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true From 375eb6f2ccaee58d3109db4f543e66b3ce48986f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 24 Dec 2024 10:47:18 -0300 Subject: [PATCH 296/335] psycopg: bump versions in test-requirements to support py313 (#3147) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .../opentelemetry-instrumentation-aiopg/test-requirements.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 58669a50f9..a3d94d65ee 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -5,7 +5,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 -psycopg2-binary==2.9.9 +psycopg2-binary==2.9.10 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index f45e3be149..f18f4522a9 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 -psycopg==3.1.18 +psycopg==3.2.2 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index 482c30222d..305185e362 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 -psycopg2==2.9.9 +psycopg2==2.9.10 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 From 396aad9c24adc4a6501e9b51e48aaa5e96c72096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 24 Dec 2024 10:55:33 -0300 Subject: [PATCH 297/335] celery: remove deprecated import of ContextManager from typing (#3145) * celery: remove deprecated import of ContextManager from typing Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * add type checking Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * ruff Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .../src/opentelemetry/instrumentation/celery/utils.py | 11 ++++++++--- .../test-requirements-1.txt | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py index 6af310df5a..d7ca77af8a 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/utils.py @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations + import logging -from typing import ContextManager, Optional, Tuple +from typing import TYPE_CHECKING, Optional, Tuple from celery import registry # pylint: disable=no-name-in-module from celery.app.task import Task @@ -21,6 +23,9 @@ from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace import Span +if TYPE_CHECKING: + from contextlib import AbstractContextManager + logger = logging.getLogger(__name__) # Celery Context key @@ -123,7 +128,7 @@ def attach_context( task: Optional[Task], task_id: str, span: Span, - activation: ContextManager[Span], + activation: AbstractContextManager[Span], token: Optional[object], is_publish: bool = False, ) -> None: @@ -171,7 +176,7 @@ def detach_context(task, task_id, is_publish=False) -> None: def retrieve_context( task, task_id, is_publish=False -) -> Optional[Tuple[Span, ContextManager[Span], Optional[object]]]: +) -> Optional[Tuple[Span, AbstractContextManager[Span], Optional[object]]]: """Helper to retrieve an active `Span`, `ContextManager` and context token stored in a `Task` instance """ diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 5ef9e5750a..4d3afc74e4 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -1,6 +1,6 @@ amqp==5.2.0 asgiref==3.8.1 -billiard==4.2.0 +billiard==4.2.1 celery==5.3.6 click==8.1.7 click-didyoumean==0.3.0 From d116ae39d6a9e66d55c7c245d980be86e1f499ec Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 24 Dec 2024 08:59:31 -0600 Subject: [PATCH 298/335] Update opentelemetry-sdk-extension-aws version to v2.2.0 (#3149) --- sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md | 2 ++ .../src/opentelemetry/sdk/extension/aws/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md index 25201d51d1..a66805003c 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md +++ b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 2.1.0 (2024-12-24) + - Make ec2 resource detector silent when loaded outside AWS ([#3120](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3120)) - Make ecs and beanstalk resource detector silent when loaded outside AWS diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py index b065755302..9d12794ffb 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.1.0.dev" +__version__ = "2.2.0.dev" From 16eaec8d03897c257dfe447545d7bdbe111734ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 24 Dec 2024 12:14:05 -0300 Subject: [PATCH 299/335] cassandra: fix tests for py313 (#3152) * cassandra: fix tests to make CI happy for py313 Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * ruff Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .../tests/test_cassandra_integration.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py b/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py index 9a36bb9069..7f1e55238c 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py @@ -43,6 +43,10 @@ def tearDown(self): with self.disable_logging(): CassandraInstrumentor().uninstrument() + @property + def _mocked_session(self): + return cassandra.cluster.Session(cluster=mock.Mock(), hosts=[]) + def test_instrument_uninstrument(self): instrumentation = CassandraInstrumentor() instrumentation.instrument() @@ -67,7 +71,7 @@ def test_instrumentor( ): mock_create_response_future.return_value = mock.Mock() mock_session_init.return_value = None - mock_connect.return_value = cassandra.cluster.Session() + mock_connect.return_value = self._mocked_session CassandraInstrumentor().instrument() @@ -100,7 +104,7 @@ def test_custom_tracer_provider( ): mock_create_response_future.return_value = mock.Mock() mock_session_init.return_value = None - mock_connect.return_value = cassandra.cluster.Session() + mock_connect.return_value = self._mocked_session resource = resources.Resource.create({}) result = self.create_tracer_provider(resource=resource) @@ -124,7 +128,7 @@ def test_instrument_connection_no_op_tracer_provider( ): mock_create_response_future.return_value = mock.Mock() mock_session_init.return_value = None - mock_connect.return_value = cassandra.cluster.Session() + mock_connect.return_value = self._mocked_session tracer_provider = trace_api.NoOpTracerProvider() CassandraInstrumentor().instrument(tracer_provider=tracer_provider) From 72dc1cf1f6c611aabd0f2aed977c54bfc6272dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 30 Dec 2024 05:26:54 -0300 Subject: [PATCH 300/335] prometheus-remote-write: bump cramjam to 2.8.4 in test-requirements (#3157) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .../test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 20d42eb4c6..5587dcdbb5 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -3,7 +3,7 @@ certifi==2024.7.4 charset-normalizer==3.3.2 # We can drop this after bumping baseline to pypy-39 cramjam==2.1.0; platform_python_implementation == "PyPy" -cramjam==2.8.1; platform_python_implementation != "PyPy" +cramjam==2.8.4; platform_python_implementation != "PyPy" Deprecated==1.2.14 idna==3.7 iniconfig==2.0.0 From 8db1479e0d2e8c7d1b122859e891fbaf1757d449 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 30 Dec 2024 14:13:07 +0100 Subject: [PATCH 301/335] RELEASING: Document what package prepare release workflows will create (#3153) While at it fix formatting --- RELEASING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASING.md b/RELEASING.md index 490269e2e4..1b96120db0 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -21,6 +21,7 @@ > - opentelemetry-resource-detector-azure > - opentelemetry-sdk-extension-aws > - opentelemetry-instrumentation-openai-v2 +> > These libraries are also excluded from the general release. Package release preparation is handled by the [`[Package] Prepare release`](./.github/workflows/package-prepare-release.yml) workflow that allows @@ -28,6 +29,8 @@ to pick a specific package to release. It follows the same versioning strategy a Long-term package release branch follows `package-release/{package-name}/v{major}.{minor}.x` (or `package-release/{package-name}/v{major}.{minor}bx`) naming pattern. +The workflow will create two pull requests, one against the `main` and one against the `package-release/` branch; both should be merged in order to proceed with the release. + ## Preparing a new patch release * Backport pull request(s) to the release branch. @@ -54,6 +57,8 @@ to pick a specific package to release. The workflow can only be run against long-term release branch such as `package-release/{package-name}/v{major}.{minor}.x` or `package-release/{package-name}/v{major}.{minor}bx`. +The workflow will create a pull request that should be merged in order to proceed with the release. + ## Making the release * Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml). From c084ca8fa5de7fe7e628e31c254d4b4826804d41 Mon Sep 17 00:00:00 2001 From: Cyrille Le Clerc Date: Tue, 31 Dec 2024 16:31:33 +0100 Subject: [PATCH 302/335] Update README.rst - Fix Markdown (#3156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix broken Markdown. Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- processor/opentelemetry-processor-baggage/README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/processor/opentelemetry-processor-baggage/README.rst b/processor/opentelemetry-processor-baggage/README.rst index 6d3a439d8a..9c49a6ff75 100644 --- a/processor/opentelemetry-processor-baggage/README.rst +++ b/processor/opentelemetry-processor-baggage/README.rst @@ -33,7 +33,8 @@ Do not put sensitive information in Baggage. To repeat: a consequence of adding data to Baggage is that the keys and values will appear in all outgoing HTTP headers from the application. -## Usage +Usage +----- Add the span processor when configuring the tracer provider. From 54882871b902ba4db422dba18d774d025f866137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 31 Dec 2024 13:08:20 -0300 Subject: [PATCH 303/335] add official support to Python 3.13 (#3134) * add py313 to tox Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix wrong identation troveclassifiers Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix pyramid, django Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix httpx Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix httpx, grpc and add vertex Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * generate-workflows Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix generate-workflows Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix celery and psycopg Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * add changelog Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * Update CHANGELOG.md * Update tox.ini --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .../generate_workflows_lib/pyproject.toml | 1 + .../src/generate_workflows_lib/__init__.py | 1 + .../src/generate_workflows_lib/lint.yml.j2 | 4 +- .github/workflows/lint_0.yml | 248 +- .github/workflows/test_0.yml | 1216 ++++----- .github/workflows/test_1.yml | 2314 ++++++++--------- .github/workflows/test_2.yml | 1440 ++++++++++ CHANGELOG.md | 3 +- _template/pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 21 +- .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + opentelemetry-distro/pyproject.toml | 1 + opentelemetry-instrumentation/pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + .../pyproject.toml | 1 + tox.ini | 124 +- util/opentelemetry-util-http/pyproject.toml | 1 + 72 files changed, 3472 insertions(+), 1962 deletions(-) diff --git a/.github/workflows/generate_workflows_lib/pyproject.toml b/.github/workflows/generate_workflows_lib/pyproject.toml index 314d079686..8fa1524442 100644 --- a/.github/workflows/generate_workflows_lib/pyproject.toml +++ b/.github/workflows/generate_workflows_lib/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Typing :: Typed", ] dependencies = ["Jinja2", "tox"] diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index e60e8e8f81..1ad36c1b10 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -53,6 +53,7 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: "py310": "3.10", "py311": "3.11", "py312": "3.12", + "py313": "3.13", } test_job_datas = [] diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 index 6959261bba..225387e352 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 @@ -24,10 +24,10 @@ jobs: - name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index 80c7902e6b..e36a6a2ad2 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -23,10 +23,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -41,10 +41,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -59,10 +59,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -77,10 +77,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -95,10 +95,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -113,10 +113,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -131,10 +131,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -149,10 +149,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -167,10 +167,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -185,10 +185,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -203,10 +203,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -221,10 +221,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -239,10 +239,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -257,10 +257,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -275,10 +275,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -293,10 +293,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -311,10 +311,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -329,10 +329,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -347,10 +347,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -365,10 +365,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -383,10 +383,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -401,10 +401,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -419,10 +419,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -437,10 +437,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -455,10 +455,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -473,10 +473,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -491,10 +491,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -509,10 +509,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -527,10 +527,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -545,10 +545,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -563,10 +563,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -581,10 +581,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -599,10 +599,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -617,10 +617,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -635,10 +635,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -653,10 +653,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -671,10 +671,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -689,10 +689,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -707,10 +707,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -725,10 +725,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -743,10 +743,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -761,10 +761,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -779,10 +779,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -797,10 +797,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -815,10 +815,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -833,10 +833,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -851,10 +851,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -869,10 +869,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -887,10 +887,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -905,10 +905,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -923,10 +923,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -941,10 +941,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -959,10 +959,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -977,10 +977,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -995,10 +995,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1013,10 +1013,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1031,10 +1031,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1049,10 +1049,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1067,10 +1067,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1085,10 +1085,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1103,10 +1103,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox @@ -1121,10 +1121,10 @@ jobs: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index a0f561010e..e651777907 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -196,6 +196,42 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-openai-v2-1 -- -ra + py313-test-instrumentation-openai-v2-0_ubuntu-latest: + name: instrumentation-openai-v2-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-openai-v2-0 -- -ra + + py313-test-instrumentation-openai-v2-1_ubuntu-latest: + name: instrumentation-openai-v2-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-openai-v2-1 -- -ra + pypy3-test-instrumentation-openai-v2-0_ubuntu-latest: name: instrumentation-openai-v2-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -412,6 +448,42 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-vertexai-1 -- -ra + py313-test-instrumentation-vertexai-0_ubuntu-latest: + name: instrumentation-vertexai-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-vertexai-0 -- -ra + + py313-test-instrumentation-vertexai-1_ubuntu-latest: + name: instrumentation-vertexai-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-vertexai-1 -- -ra + py38-test-resource-detector-container_ubuntu-latest: name: resource-detector-container 3.8 Ubuntu runs-on: ubuntu-latest @@ -502,6 +574,24 @@ jobs: - name: Run tests run: tox -e py312-test-resource-detector-container -- -ra + py313-test-resource-detector-container_ubuntu-latest: + name: resource-detector-container 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-resource-detector-container -- -ra + pypy3-test-resource-detector-container_ubuntu-latest: name: resource-detector-container pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -700,6 +790,42 @@ jobs: - name: Run tests run: tox -e py312-test-resource-detector-azure-1 -- -ra + py313-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-resource-detector-azure-0 -- -ra + + py313-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-resource-detector-azure-1 -- -ra + pypy3-test-resource-detector-azure-0_ubuntu-latest: name: resource-detector-azure-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -916,6 +1042,42 @@ jobs: - name: Run tests run: tox -e py312-test-sdk-extension-aws-1 -- -ra + py313-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-sdk-extension-aws-0 -- -ra + + py313-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-sdk-extension-aws-1 -- -ra + pypy3-test-sdk-extension-aws-0_ubuntu-latest: name: sdk-extension-aws-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1042,6 +1204,24 @@ jobs: - name: Run tests run: tox -e py312-test-distro -- -ra + py313-test-distro_ubuntu-latest: + name: distro 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-distro -- -ra + pypy3-test-distro_ubuntu-latest: name: distro pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1150,6 +1330,24 @@ jobs: - name: Run tests run: tox -e py312-test-opentelemetry-instrumentation -- -ra + py313-test-opentelemetry-instrumentation_ubuntu-latest: + name: opentelemetry-instrumentation 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-opentelemetry-instrumentation -- -ra + pypy3-test-opentelemetry-instrumentation_ubuntu-latest: name: opentelemetry-instrumentation pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1258,6 +1456,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-aiohttp-client -- -ra + py313-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aiohttp-client -- -ra + pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: name: instrumentation-aiohttp-client pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1366,6 +1582,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-aiohttp-server -- -ra + py313-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aiohttp-server -- -ra + pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: name: instrumentation-aiohttp-server pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1474,6 +1708,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-aiopg -- -ra + py313-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aiopg -- -ra + py38-test-instrumentation-aws-lambda_ubuntu-latest: name: instrumentation-aws-lambda 3.8 Ubuntu runs-on: ubuntu-latest @@ -1564,6 +1816,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-aws-lambda -- -ra + py313-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aws-lambda -- -ra + pypy3-test-instrumentation-aws-lambda_ubuntu-latest: name: instrumentation-aws-lambda pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1672,6 +1942,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-botocore -- -ra + py313-test-instrumentation-botocore_ubuntu-latest: + name: instrumentation-botocore 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore -- -ra + py38-test-instrumentation-boto3sqs_ubuntu-latest: name: instrumentation-boto3sqs 3.8 Ubuntu runs-on: ubuntu-latest @@ -1762,6 +2050,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-boto3sqs -- -ra + py313-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-boto3sqs -- -ra + pypy3-test-instrumentation-boto3sqs_ubuntu-latest: name: instrumentation-boto3sqs pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -1996,6 +2302,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-django-3 -- -ra + py313-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-django-3 -- -ra + pypy3-test-instrumentation-django-0_ubuntu-latest: name: instrumentation-django-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -2122,6 +2446,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-dbapi -- -ra + py313-test-instrumentation-dbapi_ubuntu-latest: + name: instrumentation-dbapi 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-dbapi -- -ra + pypy3-test-instrumentation-dbapi_ubuntu-latest: name: instrumentation-dbapi pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -2302,26 +2644,44 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-click -- -ra - pypy3-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click pypy-3.8 Ubuntu + py313-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-click -- -ra + run: tox -e py313-test-instrumentation-click -- -ra - py38-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.8 Ubuntu + pypy3-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-click -- -ra + + py38-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2590,6 +2950,60 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra + py313-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra + + py313-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra + + py313-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra + pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: name: instrumentation-elasticsearch-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -3004,6 +3418,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-falcon-4 -- -ra + py313-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-falcon-4 -- -ra + pypy3-test-instrumentation-falcon-0_ubuntu-latest: name: instrumentation-falcon-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -3184,6 +3616,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-fastapi -- -ra + py313-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-fastapi -- -ra + pypy3-test-instrumentation-fastapi_ubuntu-latest: name: instrumentation-fastapi pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -3238,6 +3688,24 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-flask-1 -- -ra + py38-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-flask-2 -- -ra + py39-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 3.9 Ubuntu runs-on: ubuntu-latest @@ -3274,6 +3742,24 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-flask-1 -- -ra + py39-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-2 -- -ra + py310-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -3310,6 +3796,24 @@ jobs: - name: Run tests run: tox -e py310-test-instrumentation-flask-1 -- -ra + py310-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-2 -- -ra + py311-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 3.11 Ubuntu runs-on: ubuntu-latest @@ -3346,26 +3850,26 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-flask-1 -- -ra - py312-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.12 Ubuntu + py311-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-flask-0 -- -ra + run: tox -e py311-test-instrumentation-flask-2 -- -ra - py312-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.12 Ubuntu + py312-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3380,97 +3884,97 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-flask-1 -- -ra + run: tox -e py312-test-instrumentation-flask-0 -- -ra - py38-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.8 Ubuntu + py312-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-flask-2 -- -ra + run: tox -e py312-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 Ubuntu + py312-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra + run: tox -e py312-test-instrumentation-flask-2 -- -ra - py310-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.10 Ubuntu + py313-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-flask-2 -- -ra + run: tox -e py313-test-instrumentation-flask-0 -- -ra - py311-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.11 Ubuntu + py313-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-flask-2 -- -ra + run: tox -e py313-test-instrumentation-flask-1 -- -ra - py312-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.12 Ubuntu + py313-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-flask-2 -- -ra + run: tox -e py313-test-instrumentation-flask-2 -- -ra pypy3-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 pypy-3.8 Ubuntu @@ -3598,6 +4102,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-urllib -- -ra + py313-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-urllib -- -ra + pypy3-test-instrumentation-urllib_ubuntu-latest: name: instrumentation-urllib pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -3796,6 +4318,42 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-urllib3-1 -- -ra + py313-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-urllib3-0 -- -ra + + py313-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-urllib3-1 -- -ra + pypy3-test-instrumentation-urllib3-0_ubuntu-latest: name: instrumentation-urllib3-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -3922,596 +4480,38 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-requests -- -ra - py38-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-starlette -- -ra - - py39-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.9 Ubuntu + py313-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-starlette -- -ra + run: tox -e py313-test-instrumentation-requests -- -ra - py310-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.10 Ubuntu + py38-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-starlette -- -ra - - py311-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-starlette -- -ra - - py312-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-starlette -- -ra - - pypy3-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette -- -ra - - py38-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-jinja2 -- -ra - - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra - - py310-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-jinja2 -- -ra - - py311-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-jinja2 -- -ra - - py312-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-jinja2 -- -ra - - pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - - py38-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-logging -- -ra - - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra - - py310-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-instrumentation-logging -- -ra - - py311-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-logging -- -ra - - py312-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-instrumentation-logging -- -ra - - pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-logging -- -ra - - py38-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-exporter-richconsole -- -ra - - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra - - py310-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-exporter-richconsole -- -ra - - py311-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-exporter-richconsole -- -ra - - py312-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-exporter-richconsole -- -ra - - pypy3-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-exporter-richconsole -- -ra - - py38-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-exporter-prometheus-remote-write -- -ra - - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - - py310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - - py311-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-exporter-prometheus-remote-write -- -ra - - py312-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py312-test-exporter-prometheus-remote-write -- -ra - - pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra - - py38-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-mysql-0 -- -ra - - py38-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-mysql-1 -- -ra - - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra + run: tox -e py38-test-instrumentation-starlette -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 2fce71b031..b26bb48e33 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,8 +16,8 @@ env: jobs: - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu + py39-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -32,10 +32,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e py39-test-instrumentation-starlette -- -ra - py310-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.10 Ubuntu + py310-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -50,334 +50,334 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysql-0 -- -ra + run: tox -e py310-test-instrumentation-starlette -- -ra - py310-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.10 Ubuntu + py311-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysql-1 -- -ra + run: tox -e py311-test-instrumentation-starlette -- -ra - py311-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.11 Ubuntu + py312-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysql-0 -- -ra + run: tox -e py312-test-instrumentation-starlette -- -ra - py311-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.11 Ubuntu + py313-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysql-1 -- -ra + run: tox -e py313-test-instrumentation-starlette -- -ra - py312-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.12 Ubuntu + pypy3-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysql-0 -- -ra + run: tox -e pypy3-test-instrumentation-starlette -- -ra - py312-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.12 Ubuntu + py38-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysql-1 -- -ra + run: tox -e py38-test-instrumentation-jinja2 -- -ra - pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.8 Ubuntu + py39-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra + run: tox -e py39-test-instrumentation-jinja2 -- -ra - pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.8 Ubuntu + py310-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + run: tox -e py310-test-instrumentation-jinja2 -- -ra - py38-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.8 Ubuntu + py311-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-mysqlclient -- -ra + run: tox -e py311-test-instrumentation-jinja2 -- -ra - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu + py312-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra + run: tox -e py312-test-instrumentation-jinja2 -- -ra - py310-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.10 Ubuntu + py313-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysqlclient -- -ra + run: tox -e py313-test-instrumentation-jinja2 -- -ra - py311-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.11 Ubuntu + pypy3-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysqlclient -- -ra + run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - py312-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.12 Ubuntu + py38-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysqlclient -- -ra + run: tox -e py38-test-instrumentation-logging -- -ra - pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.8 Ubuntu + py39-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra + run: tox -e py39-test-instrumentation-logging -- -ra - py38-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.8 Ubuntu + py310-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-psycopg2 -- -ra + run: tox -e py310-test-instrumentation-logging -- -ra - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu + py311-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra + run: tox -e py311-test-instrumentation-logging -- -ra - py310-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.10 Ubuntu + py312-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2 -- -ra + run: tox -e py312-test-instrumentation-logging -- -ra - py311-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.11 Ubuntu + py313-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2 -- -ra + run: tox -e py313-test-instrumentation-logging -- -ra - py312-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.12 Ubuntu + pypy3-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2 -- -ra + run: tox -e pypy3-test-instrumentation-logging -- -ra - py38-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.8 Ubuntu + py38-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -392,10 +392,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-psycopg -- -ra + run: tox -e py38-test-exporter-richconsole -- -ra - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu + py39-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -410,10 +410,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra + run: tox -e py39-test-exporter-richconsole -- -ra - py310-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.10 Ubuntu + py310-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -428,10 +428,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-psycopg -- -ra + run: tox -e py310-test-exporter-richconsole -- -ra - py311-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.11 Ubuntu + py311-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -446,10 +446,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-psycopg -- -ra + run: tox -e py311-test-exporter-richconsole -- -ra - py312-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.12 Ubuntu + py312-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -464,46 +464,46 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-psycopg -- -ra + run: tox -e py312-test-exporter-richconsole -- -ra - pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.8 Ubuntu + py313-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-psycopg -- -ra + run: tox -e py313-test-exporter-richconsole -- -ra - py38-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.8 Ubuntu + pypy3-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra + run: tox -e pypy3-test-exporter-richconsole -- -ra - py38-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.8 Ubuntu + py38-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -518,190 +518,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py38-test-exporter-prometheus-remote-write -- -ra - py38-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.8 Ubuntu + py39-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - py38-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.8 Ubuntu + py310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - py38-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.8 Ubuntu + py311-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py311-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 Ubuntu + py312-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py312-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 Ubuntu + py313-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py313-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 Ubuntu + pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu + py38-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py38-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 Ubuntu + py38-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py38-test-instrumentation-mysql-1 -- -ra - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 Ubuntu + py39-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py39-test-instrumentation-mysql-0 -- -ra - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 Ubuntu + py39-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py39-test-instrumentation-mysql-1 -- -ra - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 Ubuntu + py310-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -716,10 +716,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py310-test-instrumentation-mysql-0 -- -ra - py310-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.10 Ubuntu + py310-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -734,28 +734,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py310-test-instrumentation-mysql-1 -- -ra - py310-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.10 Ubuntu + py311-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py311-test-instrumentation-mysql-0 -- -ra - py311-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.11 Ubuntu + py311-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -770,244 +770,226 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py311-test-instrumentation-mysql-1 -- -ra - py311-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra - - py311-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.11 Ubuntu + py312-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py312-test-instrumentation-mysql-0 -- -ra - py311-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.11 Ubuntu + py312-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py312-test-instrumentation-mysql-1 -- -ra - py311-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.11 Ubuntu + py313-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py313-test-instrumentation-mysql-0 -- -ra - py312-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.12 Ubuntu + py313-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py313-test-instrumentation-mysql-1 -- -ra - py312-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.12 Ubuntu + pypy3-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra - py312-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.12 Ubuntu + pypy3-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - py312-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.12 Ubuntu + py38-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py38-test-instrumentation-mysqlclient -- -ra - py312-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.12 Ubuntu + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py39-test-instrumentation-mysqlclient -- -ra - pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 pypy-3.8 Ubuntu + py310-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-mysqlclient -- -ra - pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 pypy-3.8 Ubuntu + py311-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py311-test-instrumentation-mysqlclient -- -ra - pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 pypy-3.8 Ubuntu + py312-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py312-test-instrumentation-mysqlclient -- -ra - pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 pypy-3.8 Ubuntu + py313-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py313-test-instrumentation-mysqlclient -- -ra - pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 pypy-3.8 Ubuntu + pypy3-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1022,10 +1004,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - py38-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.8 Ubuntu + py38-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1040,10 +1022,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymongo -- -ra + run: tox -e py38-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.9 Ubuntu + py39-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1058,10 +1040,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra + run: tox -e py39-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.10 Ubuntu + py310-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1076,10 +1058,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymongo -- -ra + run: tox -e py310-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.11 Ubuntu + py311-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1094,10 +1076,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymongo -- -ra + run: tox -e py311-test-instrumentation-psycopg2 -- -ra - py312-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.12 Ubuntu + py312-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1112,28 +1094,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymongo -- -ra + run: tox -e py312-test-instrumentation-psycopg2 -- -ra - pypy3-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo pypy-3.8 Ubuntu + py313-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymongo -- -ra + run: tox -e py313-test-instrumentation-psycopg2 -- -ra - py38-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.8 Ubuntu + py38-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1148,10 +1130,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pymysql -- -ra + run: tox -e py38-test-instrumentation-psycopg -- -ra - py39-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.9 Ubuntu + py39-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1166,10 +1148,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra + run: tox -e py39-test-instrumentation-psycopg -- -ra - py310-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.10 Ubuntu + py310-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1184,10 +1166,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pymysql -- -ra + run: tox -e py310-test-instrumentation-psycopg -- -ra - py311-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.11 Ubuntu + py311-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1202,10 +1184,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymysql -- -ra + run: tox -e py311-test-instrumentation-psycopg -- -ra - py312-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.12 Ubuntu + py312-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1220,154 +1202,154 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymysql -- -ra + run: tox -e py312-test-instrumentation-psycopg -- -ra - pypy3-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql pypy-3.8 Ubuntu + py313-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pymysql -- -ra + run: tox -e py313-test-instrumentation-psycopg -- -ra - py38-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.8 Ubuntu + pypy3-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-pyramid -- -ra + run: tox -e pypy3-test-instrumentation-psycopg -- -ra - py39-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.9 Ubuntu + py38-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra + run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra - py310-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.10 Ubuntu + py38-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-pyramid -- -ra + run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra - py311-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.11 Ubuntu + py38-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pyramid -- -ra + run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra - py312-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.12 Ubuntu + py38-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pyramid -- -ra + run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra - pypy3-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid pypy-3.8 Ubuntu + py38-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-pyramid -- -ra + run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra - py38-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.8 Ubuntu + py39-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-asgi -- -ra + run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra - py39-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.9 Ubuntu + py39-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1382,118 +1364,118 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra + run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra - py310-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.10 Ubuntu + py39-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-asgi -- -ra + run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra - py311-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.11 Ubuntu + py39-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-asgi -- -ra + run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra - py312-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.12 Ubuntu + py39-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-asgi -- -ra + run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra - pypy3-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi pypy-3.8 Ubuntu + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-asgi -- -ra + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - py38-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.8 Ubuntu + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-asyncpg -- -ra + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.9 Ubuntu + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg -- -ra + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra - py310-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.10 Ubuntu + py310-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1508,100 +1490,100 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-asyncpg -- -ra + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra - py311-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.11 Ubuntu + py310-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-asyncpg -- -ra + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra - py312-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.12 Ubuntu + py311-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-asyncpg -- -ra + run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra - py38-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.8 Ubuntu + py311-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-sqlite3 -- -ra + run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.9 Ubuntu + py311-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra + run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra - py310-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.10 Ubuntu + py311-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-sqlite3 -- -ra + run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra - py311-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.11 Ubuntu + py311-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1616,10 +1598,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-sqlite3 -- -ra + run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra - py312-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.12 Ubuntu + py312-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1634,100 +1616,64 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-sqlite3 -- -ra - - pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - - py38-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox - - - name: Run tests - run: tox -e py38-test-instrumentation-wsgi -- -ra + run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu + py312-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra + run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra - py310-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.10 Ubuntu + py312-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-wsgi -- -ra + run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra - py311-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.11 Ubuntu + py312-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-wsgi -- -ra + run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra - py312-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.12 Ubuntu + py312-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1742,424 +1688,424 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-wsgi -- -ra + run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra - pypy3-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi pypy-3.8 Ubuntu + py313-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-wsgi -- -ra + run: tox -e py313-test-instrumentation-pymemcache-0 -- -ra - py38-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.8 Ubuntu + py313-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-grpc-0 -- -ra + run: tox -e py313-test-instrumentation-pymemcache-1 -- -ra - py38-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.8 Ubuntu + py313-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-grpc-1 -- -ra + run: tox -e py313-test-instrumentation-pymemcache-2 -- -ra - py39-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.9 Ubuntu + py313-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0 -- -ra + run: tox -e py313-test-instrumentation-pymemcache-3 -- -ra - py39-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.9 Ubuntu + py313-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1 -- -ra + run: tox -e py313-test-instrumentation-pymemcache-4 -- -ra - py310-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.10 Ubuntu + pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0 -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra - py310-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.10 Ubuntu + pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1 -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra - py311-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.11 Ubuntu + pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-grpc-0 -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra - py311-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.11 Ubuntu + pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-grpc-1 -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra - py312-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.12 Ubuntu + pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-grpc-0 -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra - py312-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.12 Ubuntu + py38-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-grpc-1 -- -ra + run: tox -e py38-test-instrumentation-pymongo -- -ra - py38-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.8 Ubuntu + py39-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py39-test-instrumentation-pymongo -- -ra - py38-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.8 Ubuntu + py310-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py310-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.9 Ubuntu + py311-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py311-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.9 Ubuntu + py312-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py312-test-instrumentation-pymongo -- -ra - py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.10 Ubuntu + py313-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py313-test-instrumentation-pymongo -- -ra - py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.10 Ubuntu + pypy3-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e pypy3-test-instrumentation-pymongo -- -ra - py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.11 Ubuntu + py38-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py38-test-instrumentation-pymysql -- -ra - py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.11 Ubuntu + py39-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py39-test-instrumentation-pymysql -- -ra - py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.12 Ubuntu + py310-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py310-test-instrumentation-pymysql -- -ra - py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.12 Ubuntu + py311-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py311-test-instrumentation-pymysql -- -ra - pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: - name: instrumentation-sqlalchemy-0 pypy-3.8 Ubuntu + py312-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra + run: tox -e py312-test-instrumentation-pymysql -- -ra - pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 pypy-3.8 Ubuntu + py313-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py313-test-instrumentation-pymysql -- -ra - pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 pypy-3.8 Ubuntu + pypy3-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2174,10 +2120,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e pypy3-test-instrumentation-pymysql -- -ra - py38-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.8 Ubuntu + py38-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2192,10 +2138,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-redis -- -ra + run: tox -e py38-test-instrumentation-pyramid -- -ra - py39-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.9 Ubuntu + py39-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2210,10 +2156,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra + run: tox -e py39-test-instrumentation-pyramid -- -ra - py310-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.10 Ubuntu + py310-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2228,10 +2174,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-redis -- -ra + run: tox -e py310-test-instrumentation-pyramid -- -ra - py311-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.11 Ubuntu + py311-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2246,10 +2192,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-redis -- -ra + run: tox -e py311-test-instrumentation-pyramid -- -ra - py312-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.12 Ubuntu + py312-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2264,10 +2210,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-redis -- -ra + run: tox -e py312-test-instrumentation-pyramid -- -ra - pypy3-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis pypy-3.8 Ubuntu + pypy3-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2282,10 +2228,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-redis -- -ra + run: tox -e pypy3-test-instrumentation-pyramid -- -ra - py38-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.8 Ubuntu + py38-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2300,10 +2246,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-remoulade -- -ra + run: tox -e py38-test-instrumentation-asgi -- -ra - py39-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.9 Ubuntu + py39-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2318,10 +2264,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra + run: tox -e py39-test-instrumentation-asgi -- -ra - py310-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.10 Ubuntu + py310-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2336,10 +2282,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-remoulade -- -ra + run: tox -e py310-test-instrumentation-asgi -- -ra - py311-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.11 Ubuntu + py311-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2354,10 +2300,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-remoulade -- -ra + run: tox -e py311-test-instrumentation-asgi -- -ra - py312-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.12 Ubuntu + py312-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2372,10 +2318,46 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-remoulade -- -ra + run: tox -e py312-test-instrumentation-asgi -- -ra - py38-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.8 Ubuntu + py313-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-asgi -- -ra + + pypy3-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-asgi -- -ra + + py38-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2390,10 +2372,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-celery -- -ra + run: tox -e py38-test-instrumentation-asyncpg -- -ra - py39-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.9 Ubuntu + py39-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2408,10 +2390,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra + run: tox -e py39-test-instrumentation-asyncpg -- -ra - py310-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.10 Ubuntu + py310-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2426,10 +2408,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-celery -- -ra + run: tox -e py310-test-instrumentation-asyncpg -- -ra - py311-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.11 Ubuntu + py311-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2444,10 +2426,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-celery -- -ra + run: tox -e py311-test-instrumentation-asyncpg -- -ra - py312-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.12 Ubuntu + py312-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2462,28 +2444,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-celery -- -ra + run: tox -e py312-test-instrumentation-asyncpg -- -ra - pypy3-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery pypy-3.8 Ubuntu + py313-test-instrumentation-asyncpg_ubuntu-latest: + name: instrumentation-asyncpg 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-celery -- -ra + run: tox -e py313-test-instrumentation-asyncpg -- -ra - py38-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.8 Ubuntu + py38-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2498,82 +2480,100 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-system-metrics -- -ra + run: tox -e py38-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.9 Ubuntu + py39-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlite3 -- -ra + + py310-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra + run: tox -e py310-test-instrumentation-sqlite3 -- -ra - py310-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.10 Ubuntu + py311-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-system-metrics -- -ra + run: tox -e py311-test-instrumentation-sqlite3 -- -ra - py311-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.11 Ubuntu + py312-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-system-metrics -- -ra + run: tox -e py312-test-instrumentation-sqlite3 -- -ra - py312-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.12 Ubuntu + py313-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-system-metrics -- -ra + run: tox -e py313-test-instrumentation-sqlite3 -- -ra - pypy3-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics pypy-3.8 Ubuntu + pypy3-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2588,10 +2588,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-system-metrics -- -ra + run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - py38-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.8 Ubuntu + py38-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2606,10 +2606,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-threading -- -ra + run: tox -e py38-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.9 Ubuntu + py39-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2624,10 +2624,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra + run: tox -e py39-test-instrumentation-wsgi -- -ra - py310-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.10 Ubuntu + py310-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2642,10 +2642,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-threading -- -ra + run: tox -e py310-test-instrumentation-wsgi -- -ra - py311-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.11 Ubuntu + py311-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2660,10 +2660,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-threading -- -ra + run: tox -e py311-test-instrumentation-wsgi -- -ra - py312-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.12 Ubuntu + py312-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2678,208 +2678,208 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-threading -- -ra + run: tox -e py312-test-instrumentation-wsgi -- -ra - pypy3-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading pypy-3.8 Ubuntu + py313-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-threading -- -ra + run: tox -e py313-test-instrumentation-wsgi -- -ra - py38-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.8 Ubuntu + pypy3-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-tornado -- -ra + run: tox -e pypy3-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.9 Ubuntu + py38-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra + run: tox -e py38-test-instrumentation-grpc-0 -- -ra - py310-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.10 Ubuntu + py38-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-tornado -- -ra + run: tox -e py38-test-instrumentation-grpc-1 -- -ra - py311-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.11 Ubuntu + py39-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-tornado -- -ra + run: tox -e py39-test-instrumentation-grpc-0 -- -ra - py312-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.12 Ubuntu + py39-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-tornado -- -ra + run: tox -e py39-test-instrumentation-grpc-1 -- -ra - pypy3-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado pypy-3.8 Ubuntu + py310-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-tornado -- -ra + run: tox -e py310-test-instrumentation-grpc-0 -- -ra - py38-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.8 Ubuntu + py310-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-tortoiseorm -- -ra + run: tox -e py310-test-instrumentation-grpc-1 -- -ra - py39-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.9 Ubuntu + py311-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra + run: tox -e py311-test-instrumentation-grpc-0 -- -ra - py310-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.10 Ubuntu + py311-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-tortoiseorm -- -ra + run: tox -e py311-test-instrumentation-grpc-1 -- -ra - py311-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.11 Ubuntu + py312-test-instrumentation-grpc-0_ubuntu-latest: + name: instrumentation-grpc-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-tortoiseorm -- -ra + run: tox -e py312-test-instrumentation-grpc-0 -- -ra - py312-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.12 Ubuntu + py312-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2894,28 +2894,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-tortoiseorm -- -ra + run: tox -e py312-test-instrumentation-grpc-1 -- -ra - pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm pypy-3.8 Ubuntu + py313-test-instrumentation-grpc-1_ubuntu-latest: + name: instrumentation-grpc-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra + run: tox -e py313-test-instrumentation-grpc-1 -- -ra - py38-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.8 Ubuntu + py38-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2930,10 +2930,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-httpx-0 -- -ra + run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra - py38-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.8 Ubuntu + py38-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2948,10 +2948,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-httpx-1 -- -ra + run: tox -e py38-test-instrumentation-sqlalchemy-2 -- -ra - py39-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.9 Ubuntu + py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2966,10 +2966,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0 -- -ra + run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra - py39-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.9 Ubuntu + py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -2984,10 +2984,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1 -- -ra + run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra - py310-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.10 Ubuntu + py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3002,10 +3002,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-httpx-0 -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra - py310-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.10 Ubuntu + py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3020,10 +3020,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-httpx-1 -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra - py311-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.11 Ubuntu + py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3038,10 +3038,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-httpx-0 -- -ra + run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra - py311-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.11 Ubuntu + py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3056,10 +3056,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-httpx-1 -- -ra + run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra - py312-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.12 Ubuntu + py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3074,10 +3074,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-httpx-0 -- -ra + run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra - py312-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.12 Ubuntu + py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3092,280 +3092,280 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-httpx-1 -- -ra + run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra - pypy3-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 pypy-3.8 Ubuntu + py313-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-httpx-0 -- -ra + run: tox -e py313-test-instrumentation-sqlalchemy-1 -- -ra - pypy3-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 pypy-3.8 Ubuntu + py313-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-httpx-1 -- -ra + run: tox -e py313-test-instrumentation-sqlalchemy-2 -- -ra - py38-test-util-http_ubuntu-latest: - name: util-http 3.8 Ubuntu + pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: + name: instrumentation-sqlalchemy-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-util-http -- -ra + run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra - py39-test-util-http_ubuntu-latest: - name: util-http 3.9 Ubuntu + pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-util-http -- -ra + run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra - py310-test-util-http_ubuntu-latest: - name: util-http 3.10 Ubuntu + pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-util-http -- -ra + run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra - py311-test-util-http_ubuntu-latest: - name: util-http 3.11 Ubuntu + py38-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-util-http -- -ra + run: tox -e py38-test-instrumentation-redis -- -ra - py312-test-util-http_ubuntu-latest: - name: util-http 3.12 Ubuntu + py39-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-util-http -- -ra + run: tox -e py39-test-instrumentation-redis -- -ra - pypy3-test-util-http_ubuntu-latest: - name: util-http pypy-3.8 Ubuntu + py310-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-util-http -- -ra + run: tox -e py310-test-instrumentation-redis -- -ra - py38-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.8 Ubuntu + py311-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-propagator-aws-xray-0 -- -ra + run: tox -e py311-test-instrumentation-redis -- -ra - py38-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.8 Ubuntu + py312-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-propagator-aws-xray-1 -- -ra + run: tox -e py312-test-instrumentation-redis -- -ra - py39-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.9 Ubuntu + py313-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra + run: tox -e py313-test-instrumentation-redis -- -ra - py39-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.9 Ubuntu + pypy3-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra + run: tox -e pypy3-test-instrumentation-redis -- -ra - py310-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.10 Ubuntu + py38-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-propagator-aws-xray-0 -- -ra + run: tox -e py38-test-instrumentation-remoulade -- -ra - py310-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.10 Ubuntu + py39-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-propagator-aws-xray-1 -- -ra + run: tox -e py39-test-instrumentation-remoulade -- -ra - py311-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.11 Ubuntu + py310-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-propagator-aws-xray-0 -- -ra + run: tox -e py310-test-instrumentation-remoulade -- -ra - py311-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.11 Ubuntu + py311-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3380,10 +3380,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-propagator-aws-xray-1 -- -ra + run: tox -e py311-test-instrumentation-remoulade -- -ra - py312-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.12 Ubuntu + py312-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3398,406 +3398,406 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-propagator-aws-xray-0 -- -ra + run: tox -e py312-test-instrumentation-remoulade -- -ra - py312-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.12 Ubuntu + py313-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-propagator-aws-xray-1 -- -ra + run: tox -e py313-test-instrumentation-remoulade -- -ra - pypy3-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 pypy-3.8 Ubuntu + py38-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra + run: tox -e py38-test-instrumentation-celery -- -ra - pypy3-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 pypy-3.8 Ubuntu + py39-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra + run: tox -e py39-test-instrumentation-celery -- -ra - py38-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.8 Ubuntu + py310-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-propagator-ot-trace -- -ra + run: tox -e py310-test-instrumentation-celery -- -ra - py39-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.9 Ubuntu + py311-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra + run: tox -e py311-test-instrumentation-celery -- -ra - py310-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.10 Ubuntu + py312-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-propagator-ot-trace -- -ra + run: tox -e py312-test-instrumentation-celery -- -ra - py311-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.11 Ubuntu + py313-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-propagator-ot-trace -- -ra + run: tox -e py313-test-instrumentation-celery -- -ra - py312-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.12 Ubuntu + pypy3-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-propagator-ot-trace -- -ra + run: tox -e pypy3-test-instrumentation-celery -- -ra - pypy3-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace pypy-3.8 Ubuntu + py38-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-propagator-ot-trace -- -ra + run: tox -e py38-test-instrumentation-system-metrics -- -ra - py38-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.8 Ubuntu + py39-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py39-test-instrumentation-system-metrics -- -ra - py38-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.8 Ubuntu + py310-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py310-test-instrumentation-system-metrics -- -ra - py39-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.9 Ubuntu + py311-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py311-test-instrumentation-system-metrics -- -ra - py39-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.9 Ubuntu + py312-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py312-test-instrumentation-system-metrics -- -ra - py310-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.10 Ubuntu + py313-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py313-test-instrumentation-system-metrics -- -ra - py310-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.10 Ubuntu + pypy3-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-1 -- -ra + run: tox -e pypy3-test-instrumentation-system-metrics -- -ra - py311-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.11 Ubuntu + py38-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py38-test-instrumentation-threading -- -ra - py311-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.11 Ubuntu + py39-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py39-test-instrumentation-threading -- -ra - py312-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.12 Ubuntu + py310-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py310-test-instrumentation-threading -- -ra - py312-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.12 Ubuntu + py311-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py311-test-instrumentation-threading -- -ra - pypy3-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 pypy-3.8 Ubuntu + py312-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py312-test-instrumentation-threading -- -ra - pypy3-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 pypy-3.8 Ubuntu + py313-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py313-test-instrumentation-threading -- -ra - py38-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.8 Ubuntu + pypy3-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aio-pika-0 -- -ra + run: tox -e pypy3-test-instrumentation-threading -- -ra - py38-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.8 Ubuntu + py38-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3812,154 +3812,154 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py38-test-instrumentation-tornado -- -ra - py38-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.8 Ubuntu + py39-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py39-test-instrumentation-tornado -- -ra - py38-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.8 Ubuntu + py310-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py310-test-instrumentation-tornado -- -ra - py39-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.9 Ubuntu + py311-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py311-test-instrumentation-tornado -- -ra - py39-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.9 Ubuntu + py312-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py312-test-instrumentation-tornado -- -ra - py39-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.9 Ubuntu + py313-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py313-test-instrumentation-tornado -- -ra - py39-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.9 Ubuntu + pypy3-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + run: tox -e pypy3-test-instrumentation-tornado -- -ra - py310-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.10 Ubuntu + py38-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py38-test-instrumentation-tortoiseorm -- -ra - py310-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.10 Ubuntu + py39-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py39-test-instrumentation-tortoiseorm -- -ra - py310-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.10 Ubuntu + py310-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -3974,544 +3974,544 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py310-test-instrumentation-tortoiseorm -- -ra - py310-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.10 Ubuntu + py311-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py311-test-instrumentation-tortoiseorm -- -ra - py311-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.11 Ubuntu + py312-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py312-test-instrumentation-tortoiseorm -- -ra - py311-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.11 Ubuntu + py313-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py313-test-instrumentation-tortoiseorm -- -ra - py311-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.11 Ubuntu + pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra + run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra - py311-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.11 Ubuntu + py38-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py38-test-instrumentation-httpx-0 -- -ra - py312-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.12 Ubuntu + py38-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py38-test-instrumentation-httpx-1 -- -ra - py312-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.12 Ubuntu + py39-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py39-test-instrumentation-httpx-0 -- -ra - py312-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.12 Ubuntu + py39-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py39-test-instrumentation-httpx-1 -- -ra - py312-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.12 Ubuntu + py310-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py310-test-instrumentation-httpx-0 -- -ra - pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 pypy-3.8 Ubuntu + py310-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py310-test-instrumentation-httpx-1 -- -ra - pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 pypy-3.8 Ubuntu + py311-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py311-test-instrumentation-httpx-0 -- -ra - pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 pypy-3.8 Ubuntu + py311-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py311-test-instrumentation-httpx-1 -- -ra - pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 pypy-3.8 Ubuntu + py312-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py312-test-instrumentation-httpx-0 -- -ra - py38-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.8 Ubuntu + py312-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aiokafka -- -ra + run: tox -e py312-test-instrumentation-httpx-1 -- -ra - py39-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.9 Ubuntu + py313-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra + run: tox -e py313-test-instrumentation-httpx-1 -- -ra - py310-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.10 Ubuntu + pypy3-test-instrumentation-httpx-0_ubuntu-latest: + name: instrumentation-httpx-0 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aiokafka -- -ra + run: tox -e pypy3-test-instrumentation-httpx-0 -- -ra - py311-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.11 Ubuntu + pypy3-test-instrumentation-httpx-1_ubuntu-latest: + name: instrumentation-httpx-1 pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aiokafka -- -ra + run: tox -e pypy3-test-instrumentation-httpx-1 -- -ra - py312-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.12 Ubuntu + py38-test-util-http_ubuntu-latest: + name: util-http 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aiokafka -- -ra + run: tox -e py38-test-util-http -- -ra - pypy3-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka pypy-3.8 Ubuntu + py39-test-util-http_ubuntu-latest: + name: util-http 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aiokafka -- -ra + run: tox -e py39-test-util-http -- -ra - py38-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.8 Ubuntu + py310-test-util-http_ubuntu-latest: + name: util-http 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-kafka-python -- -ra + run: tox -e py310-test-util-http -- -ra - py39-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.9 Ubuntu + py311-test-util-http_ubuntu-latest: + name: util-http 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra + run: tox -e py311-test-util-http -- -ra - py310-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.10 Ubuntu + py312-test-util-http_ubuntu-latest: + name: util-http 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-kafka-python -- -ra + run: tox -e py312-test-util-http -- -ra - py311-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.11 Ubuntu + py313-test-util-http_ubuntu-latest: + name: util-http 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-kafka-python -- -ra + run: tox -e py313-test-util-http -- -ra - py38-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.8 Ubuntu + pypy3-test-util-http_ubuntu-latest: + name: util-http pypy-3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python pypy-3.8 uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "pypy-3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-kafka-pythonng -- -ra + run: tox -e pypy3-test-util-http -- -ra - py39-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.9 Ubuntu + py38-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py38-test-propagator-aws-xray-0 -- -ra - py310-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.10 Ubuntu + py38-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.8 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.8" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py38-test-propagator-aws-xray-1 -- -ra - py311-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.11 Ubuntu + py39-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py39-test-propagator-aws-xray-0 -- -ra - py312-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.12 Ubuntu + py39-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py39-test-propagator-aws-xray-1 -- -ra - pypy3-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python pypy-3.8 Ubuntu + py310-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-kafka-python -- -ra + run: tox -e py310-test-propagator-aws-xray-0 -- -ra - pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng pypy-3.8 Ubuntu + py310-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.8" + python-version: "3.10" - name: Install tox run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py310-test-propagator-aws-xray-1 -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index b165817249..ceac5ac9ed 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -16,6 +16,1374 @@ env: jobs: + py311-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-0 -- -ra + + py311-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-1 -- -ra + + py312-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-0 -- -ra + + py312-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-1 -- -ra + + py313-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-propagator-aws-xray-0 -- -ra + + py313-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-propagator-aws-xray-1 -- -ra + + pypy3-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra + + pypy3-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra + + py38-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-propagator-ot-trace -- -ra + + py39-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-propagator-ot-trace -- -ra + + py310-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-propagator-ot-trace -- -ra + + py311-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-propagator-ot-trace -- -ra + + py312-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-propagator-ot-trace -- -ra + + py313-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-propagator-ot-trace -- -ra + + pypy3-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-propagator-ot-trace -- -ra + + py38-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sio-pika-0 -- -ra + + py38-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-sio-pika-1 -- -ra + + py39-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0 -- -ra + + py39-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-1 -- -ra + + py310-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-0 -- -ra + + py310-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-1 -- -ra + + py311-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-0 -- -ra + + py311-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-1 -- -ra + + py312-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-0 -- -ra + + py312-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-1 -- -ra + + py313-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-sio-pika-0 -- -ra + + py313-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-sio-pika-1 -- -ra + + pypy3-test-instrumentation-sio-pika-0_ubuntu-latest: + name: instrumentation-sio-pika-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-0 -- -ra + + pypy3-test-instrumentation-sio-pika-1_ubuntu-latest: + name: instrumentation-sio-pika-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-1 -- -ra + + py38-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-0 -- -ra + + py38-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-1 -- -ra + + py38-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-2 -- -ra + + py38-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aio-pika-3 -- -ra + + py39-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + + py39-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + + py39-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + + py39-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + + py310-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra + + py310-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra + + py310-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra + + py310-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra + + py311-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra + + py311-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra + + py311-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra + + py311-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra + + py312-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra + + py312-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra + + py312-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra + + py312-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra + + py313-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-0 -- -ra + + py313-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-1 -- -ra + + py313-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-2 -- -ra + + py313-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-3 -- -ra + + pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra + + pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra + + pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra + + pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra + + py38-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-aiokafka -- -ra + + py39-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-aiokafka -- -ra + + py310-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-aiokafka -- -ra + + py311-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-aiokafka -- -ra + + py312-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-aiokafka -- -ra + + py313-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-aiokafka -- -ra + + pypy3-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiokafka -- -ra + + py38-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-kafka-python -- -ra + + py39-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-kafka-python -- -ra + + py310-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-kafka-python -- -ra + + py311-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-kafka-python -- -ra + + py38-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py38-test-instrumentation-kafka-pythonng -- -ra + + py39-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + + py310-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra + + py311-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra + + py312-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra + + py313-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-kafka-pythonng -- -ra + + pypy3-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-kafka-python -- -ra + + pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra + py38-test-instrumentation-confluent-kafka_ubuntu-latest: name: instrumentation-confluent-kafka 3.8 Ubuntu runs-on: ubuntu-latest @@ -106,6 +1474,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-confluent-kafka -- -ra + py313-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-confluent-kafka -- -ra + py38-test-instrumentation-asyncio_ubuntu-latest: name: instrumentation-asyncio 3.8 Ubuntu runs-on: ubuntu-latest @@ -196,6 +1582,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-asyncio -- -ra + py313-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncio -- -ra + py38-test-instrumentation-cassandra_ubuntu-latest: name: instrumentation-cassandra 3.8 Ubuntu runs-on: ubuntu-latest @@ -286,6 +1690,24 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-cassandra -- -ra + py313-test-instrumentation-cassandra_ubuntu-latest: + name: instrumentation-cassandra 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-instrumentation-cassandra -- -ra + pypy3-test-instrumentation-cassandra_ubuntu-latest: name: instrumentation-cassandra pypy-3.8 Ubuntu runs-on: ubuntu-latest @@ -394,6 +1816,24 @@ jobs: - name: Run tests run: tox -e py312-test-processor-baggage -- -ra + py313-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e py313-test-processor-baggage -- -ra + pypy3-test-processor-baggage_ubuntu-latest: name: processor-baggage pypy-3.8 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index d17c18687c..7de249bf2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) - `opentelemetry-instrumentation-falcon` add support version to v4 ([#3086](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3086)) - +- add support to Python 3.13 + ([#3134](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3134)) ### Fixed diff --git a/_template/pyproject.toml b/_template/pyproject.toml index bb60cb1578..0555456b7b 100644 --- a/_template/pyproject.toml +++ b/_template/pyproject.toml @@ -27,6 +27,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml index 78db2c6cb5..23801d1c04 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "protobuf ~= 4.21", diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 140e6c6080..d445a94761 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index 88e559a511..fdc0afc9c0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.28", diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 3e21377aff..9b4e76d547 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.5", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index 4d2d626786..879f10f43c 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 7b0cf4c501..2d44aff1b2 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -13,16 +13,17 @@ authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io"} ] classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index 0787695f26..b6379d8068 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.27", diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 4b55ea8dfe..c86a669396 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 40a9e3e49b..e1788334c3 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "asgiref ~= 3.0", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index 279b2709b4..7836b17f3f 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.14", diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 9ba7a060d5..53caf26581 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index a5f9f44f13..6b4e5d9199 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-instrumentation == 0.51b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml index 065e8ec79d..15c6616908 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 6f24df391b..235968f5cb 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index ddf246a114..fe59236d52 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 771199ddfa..8e3a724acc 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 6f37573860..dea0d4fb46 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index 43a95f5cae..a6ec7e81a4 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 2694dcedc7..2a1318c4e7 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-instrumentation == 0.51b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index 8b4e96ba32..abca1d40ab 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index 27b5865033..e19f06e54c 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 7a8899bd14..a54c827649 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index a2ccb77998..5a416d216a 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 34e3450540..17f00837b4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index c0945a8935..a0c80c23be 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index c1239d7ebd..cabbb40a4b 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 1138704387..05bd729c36 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index 9c853efd52..9c7b573ca4 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index a6868816c0..8d4716524e 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.5", diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index ef1442b574..bb8c87f035 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index 6e74ba69b6..8bc34c775c 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index 2b827f8667..56f67f90a7 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 655cb5a7ee..7b027be7dc 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-instrumentation == 0.51b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index e2cf929371..4352ba4a8e 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index d73fbc020a..c8ce3e8dfa 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 6da560c333..6fef4c284e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index 55926c5591..cfb94e4294 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index a806ff9ce4..434493dce2 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index c72a22a53e..18944afab4 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 4ffaeef263..2d5450189d 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 76ad80c786..628b698cc9 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index e4c5e63742..9d27fdbb7f 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index 1c758e19e8..dd06af2de4 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index d10a280c47..e006ae9b86 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 6a0a011245..279fd35d93 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 867c21a8d4..42ed452cd1 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-instrumentation == 0.51b0.dev", diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 59aeb4e6b4..e7478709b6 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index b20805fa3c..cfc08f40fc 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 71dfe82508..2ee1e00161 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 62e272a4d1..7b0abcf278 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 214d3e8fb8..391a344dd9 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index 1e6a85f758..a36418110f 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index bded7f840a..e19c0d69d8 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -27,6 +27,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-instrumentation-aio-pika==0.51b0.dev", diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 3acea19815..3e6050946b 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Typing :: Typed", ] dependencies = [ diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index 54e717d4c8..4f80b22491 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.4", diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 6e9681fe99..f08cc6ccc9 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.5", diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 0307db4a8e..98fc28f06e 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.16", diff --git a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml index 5793d55870..45965e7b95 100644 --- a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml +++ b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-api ~= 1.12", diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index a1bd1dc37c..7216d2b73d 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-sdk ~= 1.21", diff --git a/resource/opentelemetry-resource-detector-container/pyproject.toml b/resource/opentelemetry-resource-detector-container/pyproject.toml index ba38089465..f70d35e56e 100644 --- a/resource/opentelemetry-resource-detector-container/pyproject.toml +++ b/resource/opentelemetry-resource-detector-container/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-sdk ~= 1.12", diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml index fb7e4cecf2..edf4522853 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml +++ b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "opentelemetry-sdk ~= 1.12", diff --git a/tox.ini b/tox.ini index 6c6abe3d42..2f1c0a577e 100644 --- a/tox.ini +++ b/tox.ini @@ -7,70 +7,70 @@ envlist = ; for specifying supported Python versions per package. ; instrumentation-openai - py3{8,9,10,11,12}-test-instrumentation-openai-v2-{0,1} + py3{8,9,10,11,12,13}-test-instrumentation-openai-v2-{0,1} pypy3-test-instrumentation-openai-v2-{0,1} lint-instrumentation-openai-v2 ; instrumentation-vertexai - py3{8,9,10,11,12}-test-instrumentation-vertexai-{0,1} + py3{8,9,10,11,12,13}-test-instrumentation-vertexai-{0,1} # Disabling pypy3 as shapely does not have wheels and fails to compile # pypy3-test-instrumentation-vertexai-{0,1} lint-instrumentation-vertexai ; opentelemetry-resource-detector-container - py3{8,9,10,11,12}-test-resource-detector-container + py3{8,9,10,11,12,13}-test-resource-detector-container pypy3-test-resource-detector-container lint-resource-detector-container ; opentelemetry-resource-detector-azure - py3{8,9,10,11,12}-test-resource-detector-azure-{0,1} + py3{8,9,10,11,12,13}-test-resource-detector-azure-{0,1} pypy3-test-resource-detector-azure-{0,1} lint-resource-detector-azure ; opentelemetry-sdk-extension-aws - py3{8,9,10,11,12}-test-sdk-extension-aws-{0,1} + py3{8,9,10,11,12,13}-test-sdk-extension-aws-{0,1} pypy3-test-sdk-extension-aws-{0,1} lint-sdk-extension-aws benchmark-sdk-extension-aws ; opentelemetry-distro - py3{8,9,10,11,12}-test-distro + py3{8,9,10,11,12,13}-test-distro pypy3-test-distro lint-distro ; opentelemetry-instrumentation - py3{8,9,10,11,12}-test-opentelemetry-instrumentation + py3{8,9,10,11,12,13}-test-opentelemetry-instrumentation pypy3-test-opentelemetry-instrumentation lint-opentelemetry-instrumentation ; opentelemetry-instrumentation-aiohttp-client - py3{8,9,10,11,12}-test-instrumentation-aiohttp-client + py3{8,9,10,11,12,13}-test-instrumentation-aiohttp-client pypy3-test-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client ; opentelemetry-instrumentation-aiohttp-server - py3{8,9,10,11,12}-test-instrumentation-aiohttp-server + py3{8,9,10,11,12,13}-test-instrumentation-aiohttp-server pypy3-test-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server ; opentelemetry-instrumentation-aiopg - py3{8,9,10,11,12}-test-instrumentation-aiopg + py3{8,9,10,11,12,13}-test-instrumentation-aiopg ; instrumentation-aiopg intentionally excluded from pypy3 lint-instrumentation-aiopg ; opentelemetry-instrumentation-aws-lambda - py3{8,9,10,11,12}-test-instrumentation-aws-lambda + py3{8,9,10,11,12,13}-test-instrumentation-aws-lambda pypy3-test-instrumentation-aws-lambda lint-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{8,9,10,11,12}-test-instrumentation-botocore + py3{8,9,10,11,12,13}-test-instrumentation-botocore ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore ; opentelemetry-instrumentation-boto3sqs - py3{8,9,10,11,12}-test-instrumentation-boto3sqs + py3{8,9,10,11,12,13}-test-instrumentation-boto3sqs pypy3-test-instrumentation-boto3sqs lint-instrumentation-boto3sqs @@ -86,11 +86,12 @@ envlist = ; 3: django>=4.0b1,<5.0 py3{8,9}-test-instrumentation-django-{0,1,2} py3{10,11,12}-test-instrumentation-django-{1,3} + py313-test-instrumentation-django-3 pypy3-test-instrumentation-django-{0,1} lint-instrumentation-django ; opentelemetry-instrumentation-dbapi - py3{8,9,10,11,12}-test-instrumentation-dbapi + py3{8,9,10,11,12,13}-test-instrumentation-dbapi pypy3-test-instrumentation-dbapi lint-instrumentation-dbapi @@ -101,7 +102,7 @@ envlist = lint-instrumentation-boto ; opentelemetry-instrumentation-click - py3{8,9,10,11,12}-test-instrumentation-click + py3{8,9,10,11,12,13}-test-instrumentation-click pypy3-test-instrumentation-click lint-instrumentation-click @@ -111,7 +112,7 @@ envlist = ; 0: elasticsearch-dsl==6.4.0 elasticsearch==6.8.2 ; 1: elasticsearch-dsl==7.4.1 elasticsearch==7.17.9 ; 2: elasticsearch-dsl==8.13.1 elasticsearch==8.13.1 - py3{8,9,10,11,12}-test-instrumentation-elasticsearch-{0,1,2} + py3{8,9,10,11,12,13}-test-instrumentation-elasticsearch-{0,1,2} pypy3-test-instrumentation-elasticsearch-{0,1,2} lint-instrumentation-elasticsearch @@ -127,11 +128,12 @@ envlist = ; 4: falcon >=4.0.0,<5.0.0 py3{8,9}-test-instrumentation-falcon-{0,1,2,3} py3{10,11,12}-test-instrumentation-falcon-{1,2,3,4} + py313-test-instrumentation-falcon-4 pypy3-test-instrumentation-falcon-{0,1,2,3,4} lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi - py3{8,9,10,11,12}-test-instrumentation-fastapi + py3{8,9,10,11,12,13}-test-instrumentation-fastapi pypy3-test-instrumentation-fastapi lint-instrumentation-fastapi @@ -141,13 +143,12 @@ envlist = ; 0: Flask ==2.1.3 Werkzeug <3.0.0 ; 1: Flask ==2.2.0 Werkzeug <3.0.0 ; 2: Flask >=3.0.0 Werkzeug >=3.0.0 - py3{8,9,10,11,12}-test-instrumentation-flask-{0,1} - py3{8,9,10,11,12}-test-instrumentation-flask-{2} + py3{8,9,10,11,12,13}-test-instrumentation-flask-{0,1,2} pypy3-test-instrumentation-flask-{0,1} lint-instrumentation-flask ; opentelemetry-instrumentation-urllib - py3{8,9,10,11,12}-test-instrumentation-urllib + py3{8,9,10,11,12,13}-test-instrumentation-urllib pypy3-test-instrumentation-urllib lint-instrumentation-urllib @@ -156,37 +157,37 @@ envlist = ; below mean these dependencies are being used: ; 0: urllib3 >=1.0.0,<2.0.0 ; 1: urllib3 >=2.0.0,<3.0.0 - py3{8,9,10,11,12}-test-instrumentation-urllib3-{0,1} + py3{8,9,10,11,12,13}-test-instrumentation-urllib3-{0,1} pypy3-test-instrumentation-urllib3-{0,1} lint-instrumentation-urllib3 ; opentelemetry-instrumentation-requests - py3{8,9,10,11,12}-test-instrumentation-requests + py3{8,9,10,11,12,13}-test-instrumentation-requests ;pypy3-test-instrumentation-requests lint-instrumentation-requests ; opentelemetry-instrumentation-starlette - py3{8,9,10,11,12}-test-instrumentation-starlette + py3{8,9,10,11,12,13}-test-instrumentation-starlette pypy3-test-instrumentation-starlette lint-instrumentation-starlette ; opentelemetry-instrumentation-jinja2 - py3{8,9,10,11,12}-test-instrumentation-jinja2 + py3{8,9,10,11,12,13}-test-instrumentation-jinja2 pypy3-test-instrumentation-jinja2 lint-instrumentation-jinja2 ; opentelemetry-instrumentation-logging - py3{8,9,10,11,12}-test-instrumentation-logging + py3{8,9,10,11,12,13}-test-instrumentation-logging pypy3-test-instrumentation-logging lint-instrumentation-logging ; opentelemetry-exporter-richconsole - py3{8,9,10,11,12}-test-exporter-richconsole + py3{8,9,10,11,12,13}-test-exporter-richconsole pypy3-test-exporter-richconsole lint-exporter-richconsole ; opentelemetry-exporter-prometheus-remote-write - py3{8,9,10,11,12}-test-exporter-prometheus-remote-write + py3{8,9,10,11,12,13}-test-exporter-prometheus-remote-write pypy3-test-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write @@ -195,12 +196,12 @@ envlist = ; below mean these dependencies are being used: ; 0: mysql-connector-python >=8.0.0,<9.0.0 ; 1: mysql-connector-python ~=9.0.0 - py3{8,9,10,11,12}-test-instrumentation-mysql-{0,1} + py3{8,9,10,11,12,13}-test-instrumentation-mysql-{0,1} pypy3-test-instrumentation-mysql-{0,1} lint-instrumentation-mysql ; opentelemetry-instrumentation-mysqlclient - py3{8,9,10,11,12}-test-instrumentation-mysqlclient + py3{8,9,10,11,12,13}-test-instrumentation-mysqlclient pypy3-test-instrumentation-mysqlclient ; prerequisite: follow the instructions here ; https://github.com/PyMySQL/mysqlclient#install @@ -208,12 +209,12 @@ envlist = lint-instrumentation-mysqlclient ; opentelemetry-instrumentation-psycopg2 - py3{8,9,10,11,12}-test-instrumentation-psycopg2 + py3{8,9,10,11,12,13}-test-instrumentation-psycopg2 ; ext-psycopg2 intentionally excluded from pypy3 lint-instrumentation-psycopg2 ; opentelemetry-instrumentation-psycopg - py3{8,9,10,11,12}-test-instrumentation-psycopg + py3{8,9,10,11,12,13}-test-instrumentation-psycopg pypy3-test-instrumentation-psycopg lint-instrumentation-psycopg @@ -225,42 +226,43 @@ envlist = ; 2: pymemcache >3.0.0,<3.4.2 ; 3: pymemcache ==3.4.2 ; 4: pymemcache ==4.0.0 - py3{8,9,10,11,12}-test-instrumentation-pymemcache-{0,1,2,3,4} + py3{8,9,10,11,12,13}-test-instrumentation-pymemcache-{0,1,2,3,4} pypy3-test-instrumentation-pymemcache-{0,1,2,3,4} lint-instrumentation-pymemcache ; opentelemetry-instrumentation-pymongo - py3{8,9,10,11,12}-test-instrumentation-pymongo + py3{8,9,10,11,12,13}-test-instrumentation-pymongo pypy3-test-instrumentation-pymongo lint-instrumentation-pymongo ; opentelemetry-instrumentation-pymysql - py3{8,9,10,11,12}-test-instrumentation-pymysql + py3{8,9,10,11,12,13}-test-instrumentation-pymysql pypy3-test-instrumentation-pymysql lint-instrumentation-pymysql ; opentelemetry-instrumentation-pyramid + ; TODO: add py313 when supported by pyramid py3{8,9,10,11,12}-test-instrumentation-pyramid pypy3-test-instrumentation-pyramid lint-instrumentation-pyramid ; opentelemetry-instrumentation-asgi - py3{8,9,10,11,12}-test-instrumentation-asgi + py3{8,9,10,11,12,13}-test-instrumentation-asgi pypy3-test-instrumentation-asgi lint-instrumentation-asgi ; opentelemetry-instrumentation-asyncpg - py3{8,9,10,11,12}-test-instrumentation-asyncpg + py3{8,9,10,11,12,13}-test-instrumentation-asyncpg ; ext-asyncpg intentionally excluded from pypy3 lint-instrumentation-asyncpg ; opentelemetry-instrumentation-sqlite3 - py3{8,9,10,11,12}-test-instrumentation-sqlite3 + py3{8,9,10,11,12,13}-test-instrumentation-sqlite3 pypy3-test-instrumentation-sqlite3 lint-instrumentation-sqlite3 ; opentelemetry-instrumentation-wsgi - py3{8,9,10,11,12}-test-instrumentation-wsgi + py3{8,9,10,11,12,13}-test-instrumentation-wsgi pypy3-test-instrumentation-wsgi lint-instrumentation-wsgi @@ -270,6 +272,7 @@ envlist = ; 0: grpcio==1.62.0 ; 1: grpcio==1.66.2 py3{8,9,10,11,12}-test-instrumentation-grpc-{0,1} + py313-test-instrumentation-grpc-1 lint-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy @@ -278,42 +281,42 @@ envlist = ; 0: sqlalchemy>=1.1,<1.2 ; 1: sqlalchemy~=1.4 aiosqlite ; 2: sqlalchemy~=2.0.0 - py3{8,9,10,11,12}-test-instrumentation-sqlalchemy-{1,2} + py3{8,9,10,11,12,13}-test-instrumentation-sqlalchemy-{1,2} pypy3-test-instrumentation-sqlalchemy-{0,1,2} lint-instrumentation-sqlalchemy ; opentelemetry-instrumentation-redis - py3{8,9,10,11,12}-test-instrumentation-redis + py3{8,9,10,11,12,13}-test-instrumentation-redis pypy3-test-instrumentation-redis lint-instrumentation-redis ; opentelemetry-instrumentation-remoulade - py3{8,9,10,11,12}-test-instrumentation-remoulade + py3{8,9,10,11,12,13}-test-instrumentation-remoulade ; instrumentation-remoulade intentionally excluded from pypy3 lint-instrumentation-remoulade ; opentelemetry-instrumentation-celery - py3{8,9,10,11,12}-test-instrumentation-celery + py3{8,9,10,11,12,13}-test-instrumentation-celery pypy3-test-instrumentation-celery lint-instrumentation-celery ; opentelemetry-instrumentation-system-metrics - py3{8,9,10,11,12}-test-instrumentation-system-metrics + py3{8,9,10,11,12,13}-test-instrumentation-system-metrics pypy3-test-instrumentation-system-metrics lint-instrumentation-system-metrics ; opentelemetry-instrumentation-threading - py3{8,9,10,11,12}-test-instrumentation-threading + py3{8,9,10,11,12,13}-test-instrumentation-threading pypy3-test-instrumentation-threading lint-instrumentation-threading ; opentelemetry-instrumentation-tornado - py3{8,9,10,11,12}-test-instrumentation-tornado + py3{8,9,10,11,12,13}-test-instrumentation-tornado pypy3-test-instrumentation-tornado lint-instrumentation-tornado ; opentelemetry-instrumentation-tortoiseorm - py3{8,9,10,11,12}-test-instrumentation-tortoiseorm + py3{8,9,10,11,12,13}-test-instrumentation-tortoiseorm pypy3-test-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm @@ -323,22 +326,23 @@ envlist = ; 0: httpx>=0.18.0,<0.19.0 respx~=0.17.0 ; 1: httpx>=0.19.0 respx~=0.20.1 py3{8,9,10,11,12}-test-instrumentation-httpx-{0,1} + py313-test-instrumentation-httpx-1 pypy3-test-instrumentation-httpx-{0,1} lint-instrumentation-httpx ; opentelemetry-util-http - py3{8,9,10,11,12}-test-util-http + py3{8,9,10,11,12,13}-test-util-http pypy3-test-util-http lint-util-http ; opentelemetry-propagator-aws-xray - py3{8,9,10,11,12}-test-propagator-aws-xray-{0,1} + py3{8,9,10,11,12,13}-test-propagator-aws-xray-{0,1} pypy3-test-propagator-aws-xray-{0,1} lint-propagator-aws-xray benchmark-propagator-aws-xray ; opentelemetry-propagator-ot-trace - py3{8,9,10,11,12}-test-propagator-ot-trace + py3{8,9,10,11,12,13}-test-propagator-ot-trace pypy3-test-propagator-ot-trace lint-propagator-ot-trace @@ -347,7 +351,7 @@ envlist = ; below mean these dependencies are being used: ; 0: pika>=0.12.0,<1.0.0 ; 1: pika>=1.0.0 - py3{8,9,10,11,12}-test-instrumentation-sio-pika-{0,1} + py3{8,9,10,11,12,13}-test-instrumentation-sio-pika-{0,1} pypy3-test-instrumentation-sio-pika-{0,1} lint-instrumentation-sio-pika @@ -358,37 +362,37 @@ envlist = ; 1: aio_pika==8.3.0 ; 2: aio_pika==9.0.5 ; 3: aio_pika==9.4.1 - py3{8,9,10,11,12}-test-instrumentation-aio-pika-{0,1,2,3} + py3{8,9,10,11,12,13}-test-instrumentation-aio-pika-{0,1,2,3} pypy3-test-instrumentation-aio-pika-{0,1,2,3} lint-instrumentation-aio-pika ; opentelemetry-instrumentation-aiokafka - py3{8,9,10,11,12}-test-instrumentation-aiokafka + py3{8,9,10,11,12,13}-test-instrumentation-aiokafka pypy3-test-instrumentation-aiokafka lint-instrumentation-aiokafka ; opentelemetry-instrumentation-kafka-python py3{8,9,10,11}-test-instrumentation-kafka-python - py3{8,9,10,11,12}-test-instrumentation-kafka-pythonng + py3{8,9,10,11,12,13}-test-instrumentation-kafka-pythonng pypy3-test-instrumentation-kafka-python pypy3-test-instrumentation-kafka-pythonng lint-instrumentation-kafka-python ; opentelemetry-instrumentation-confluent-kafka - py3{8,9,10,11,12}-test-instrumentation-confluent-kafka + py3{8,9,10,11,12,13}-test-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka ; opentelemetry-instrumentation-asyncio - py3{8,9,10,11,12}-test-instrumentation-asyncio + py3{8,9,10,11,12,13}-test-instrumentation-asyncio lint-instrumentation-asyncio ; opentelemetry-instrumentation-cassandra - py3{8,9,10,11,12}-test-instrumentation-cassandra + py3{8,9,10,11,12,13}-test-instrumentation-cassandra pypy3-test-instrumentation-cassandra lint-instrumentation-cassandra ; opentelemetry-processor-baggage - py3{8,9,10,11,12}-test-processor-baggage + py3{8,9,10,11,12,13}-test-processor-baggage pypy3-test-processor-baggage ; requires snappy headers to be available on the system lint-processor-baggage @@ -437,7 +441,7 @@ deps = celery: {[testenv]test_deps} py3{8,9}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt - py3{10,11,12}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt + py3{10,11,12,13}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt pypy3-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt lint-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -524,7 +528,7 @@ deps = py3{8,9}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt py3{8,9}-test-instrumentation-django-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt py3{10,11,12}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{10,11,12}-test-instrumentation-django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt + py3{10,11,12,13}-test-instrumentation-django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt pypy3-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt pypy3-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt lint-instrumentation-django: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -553,7 +557,7 @@ deps = psycopg: {[testenv]test_deps} py3{8,9}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt - py3{10,11,12}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt + py3{10,11,12,13}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt pypy3-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt lint-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt diff --git a/util/opentelemetry-util-http/pyproject.toml b/util/opentelemetry-util-http/pyproject.toml index 23b4d3efc1..a386deba2e 100644 --- a/util/opentelemetry-util-http/pyproject.toml +++ b/util/opentelemetry-util-http/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] [project.urls] From 16c041e22bc7caf8b139d7aee00b0b0719ab4d2c Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Thu, 2 Jan 2025 20:15:01 +0100 Subject: [PATCH 304/335] Support PEP 561 to `opentelemetry-instrumentation-sqlite3` (#3133) --- CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/sqlite3/py.typed | 0 2 files changed, 2 insertions(+) create mode 100644 instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 7de249bf2c..6bc8eb44f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) +- `opentelemetry-opentelemetry-sqlite3` Add `py.typed` file to enable PEP 561 + ([#3133](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3133)) - `opentelemetry-instrumentation-falcon` add support version to v4 ([#3086](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3086)) - add support to Python 3.13 diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/py.typed b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 3e394a4814527d6cd37aade3ac3b9dc4d2349e14 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Thu, 2 Jan 2025 20:30:41 +0100 Subject: [PATCH 305/335] Support PEP 561 to `opentelemetry-instrumentation-system-metrics` (#3132) --- CHANGELOG.md | 2 ++ .../instrumentation/system_metrics/__init__.py | 16 ++++++++-------- .../instrumentation/system_metrics/py.typed | 0 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bc8eb44f4..dfe1997d70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) +- `opentelemetry-instrumentation-system-metrics` Add `py.typed` file to enable PEP 561 + ([#3132](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3132)) - `opentelemetry-opentelemetry-sqlite3` Add `py.typed` file to enable PEP 561 ([#3133](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3133)) - `opentelemetry-instrumentation-falcon` add support version to v4 diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index aff86ea77b..a81c5bf7ff 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py @@ -76,18 +76,18 @@ --- """ +from __future__ import annotations + import gc import logging import os import sys import threading from platform import python_implementation -from typing import Collection, Dict, Iterable, List, Optional +from typing import Any, Collection, Iterable import psutil -# FIXME Remove this pylint disabling line when Github issue is cleared -# pylint: disable=no-name-in-module from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.system_metrics.package import _instruments from opentelemetry.instrumentation.system_metrics.version import __version__ @@ -96,7 +96,7 @@ _logger = logging.getLogger(__name__) -_DEFAULT_CONFIG = { +_DEFAULT_CONFIG: dict[str, list[str] | None] = { "system.cpu.time": ["idle", "user", "system", "irq"], "system.cpu.utilization": ["idle", "user", "system", "irq"], "system.memory.usage": ["used", "free", "cached"], @@ -129,8 +129,8 @@ class SystemMetricsInstrumentor(BaseInstrumentor): def __init__( self, - labels: Optional[Dict[str, str]] = None, - config: Optional[Dict[str, List[str]]] = None, + labels: dict[str, str] | None = None, + config: dict[str, list[str] | None] | None = None, ): super().__init__() if config is None: @@ -176,7 +176,7 @@ def __init__( def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): # pylint: disable=too-many-branches meter_provider = kwargs.get("meter_provider") self._meter = get_meter( @@ -408,7 +408,7 @@ def _instrument(self, **kwargs): description="Number of file descriptors in use by the process.", ) - def _uninstrument(self, **__): + def _uninstrument(self, **kwargs: Any): pass def _get_open_file_descriptors( diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/py.typed b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/py.typed new file mode 100644 index 0000000000..e69de29bb2 From e5eb524e8985a853518507320913ea1defba99aa Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Thu, 2 Jan 2025 20:44:58 +0100 Subject: [PATCH 306/335] Improve type hints in `opentelemetry.instrumentation.utils` (#3128) --- .../opentelemetry/instrumentation/utils.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index a0d9ae18f9..d5bf5db7fd 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -12,11 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations + import urllib.parse from contextlib import contextmanager from importlib import import_module from re import escape, sub -from typing import Dict, Iterable, Sequence, Union +from typing import Any, Dict, Generator, Sequence from wrapt import ObjectProxy @@ -44,9 +46,9 @@ def extract_attributes_from_object( - obj: any, attributes: Sequence[str], existing: Dict[str, str] = None + obj: Any, attributes: Sequence[str], existing: Dict[str, str] | None = None ) -> Dict[str, str]: - extracted = {} + extracted: dict[str, str] = {} if existing: extracted.update(existing) for attr in attributes: @@ -81,7 +83,7 @@ def http_status_to_status_code( return StatusCode.ERROR -def unwrap(obj: Union[object, str], attr: str): +def unwrap(obj: object, attr: str): """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it The object containing the function to unwrap may be passed as dotted module path string. @@ -152,7 +154,7 @@ def _start_internal_or_server_span( return span, token -def _url_quote(s) -> str: # pylint: disable=invalid-name +def _url_quote(s: Any) -> str: # pylint: disable=invalid-name if not isinstance(s, (str, bytes)): return s quoted = urllib.parse.quote(s) @@ -163,13 +165,13 @@ def _url_quote(s) -> str: # pylint: disable=invalid-name return quoted.replace("%", "%%") -def _get_opentelemetry_values() -> dict: +def _get_opentelemetry_values() -> dict[str, Any]: """ Return the OpenTelemetry Trace and Span IDs if Span ID is set in the OpenTelemetry execution context. """ # Insert the W3C TraceContext generated - _headers = {} + _headers: dict[str, Any] = {} propagator.inject(_headers) return _headers @@ -196,7 +198,7 @@ def is_http_instrumentation_enabled() -> bool: @contextmanager -def _suppress_instrumentation(*keys: str) -> Iterable[None]: +def _suppress_instrumentation(*keys: str) -> Generator[None]: """Suppress instrumentation within the context.""" ctx = context.get_current() for key in keys: @@ -209,7 +211,7 @@ def _suppress_instrumentation(*keys: str) -> Iterable[None]: @contextmanager -def suppress_instrumentation() -> Iterable[None]: +def suppress_instrumentation() -> Generator[None]: """Suppress instrumentation within the context.""" with _suppress_instrumentation( _SUPPRESS_INSTRUMENTATION_KEY, _SUPPRESS_INSTRUMENTATION_KEY_PLAIN @@ -218,7 +220,7 @@ def suppress_instrumentation() -> Iterable[None]: @contextmanager -def suppress_http_instrumentation() -> Iterable[None]: +def suppress_http_instrumentation() -> Generator[None]: """Suppress instrumentation within the context.""" with _suppress_instrumentation(_SUPPRESS_HTTP_INSTRUMENTATION_KEY): yield From 95f14cd8df05b87b564024d47d14f29211f3b98e Mon Sep 17 00:00:00 2001 From: GonzaloGuasch Date: Thu, 2 Jan 2025 16:58:17 -0300 Subject: [PATCH 307/335] wsgi: always record span status code to have it available in metrics (#3148) --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/wsgi/__init__.py | 4 ---- .../tests/test_wsgi_middleware.py | 13 +++++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfe1997d70..8a4de30776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3133](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3133)) - `opentelemetry-instrumentation-falcon` add support version to v4 ([#3086](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3086)) +- `opentelemetry-instrumentation-wsgi` always record span status code to have it available in metrics + ([#3148](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3148)) - add support to Python 3.13 ([#3134](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3134)) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index eb7cbced9c..bd3b2d18db 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -480,11 +480,7 @@ def add_response_attributes( """Adds HTTP response attributes to span using the arguments passed to a PEP3333-conforming start_response callable. """ - if not span.is_recording(): - return status_code_str, _ = start_response_status.split(" ", 1) - - status_code = 0 try: status_code = int(status_code_str) except ValueError: diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py index da1a3c2696..9d7d1240a7 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py @@ -779,6 +779,19 @@ def test_response_attributes(self): self.span.set_attribute.assert_has_calls(expected, any_order=True) self.span.set_attribute.assert_has_calls(expected_new, any_order=True) + def test_response_attributes_noop(self): + mock_span = mock.Mock() + mock_span.is_recording.return_value = False + + attrs = {} + otel_wsgi.add_response_attributes( + mock_span, "404 Not Found", {}, duration_attrs=attrs + ) + + self.assertEqual(mock_span.set_attribute.call_count, 0) + self.assertEqual(mock_span.is_recording.call_count, 2) + self.assertEqual(attrs[SpanAttributes.HTTP_STATUS_CODE], 404) + def test_credential_removal(self): self.environ["HTTP_HOST"] = "username:password@mock" self.environ["PATH_INFO"] = "/status/200" From 3d5935f4f65f5ead41403d5b172f651ca0e533b3 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Thu, 2 Jan 2025 21:18:07 +0100 Subject: [PATCH 308/335] docs: add missing import to aws-lambda (#3154) --- .../src/opentelemetry/instrumentation/aws_lambda/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index b31e6dea72..b1f61b9ce8 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -55,6 +55,7 @@ def lambda_handler(event, context): .. code:: python from opentelemetry.instrumentation.aws_lambda import AwsLambdaInstrumentor + from opentelemetry.propagate import get_global_textmap def custom_event_context_extractor(lambda_event): # If the `TraceContextTextMapPropagator` is the global propagator, we From 147e3f754e9cc94c16371cc177d7f968c3e60693 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Wed, 8 Jan 2025 01:02:55 -0800 Subject: [PATCH 309/335] Add check before iterating over dist.requires at load_instrumentor (#3168) * Add check before iterate over dist.requires * Changelog * Add test --- CHANGELOG.md | 2 ++ .../instrumentation/dependencies.py | 15 ++++++++------- .../tests/test_dependencies.py | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a4de30776..80d63d0395 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints ([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105)) +- `opentelemetry-instrumentation` Fix `get_dist_dependency_conflicts` if no distribution requires + ([#3168](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3168)) ## Version 1.29.0/0.50b0 (2024-12-11) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py index 8f0a383412..b7e4cff400 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py @@ -47,13 +47,14 @@ def get_dist_dependency_conflicts( extra = "extra" instruments = "instruments" instruments_marker = {extra: instruments} - for dep in dist.requires: - if extra not in dep or instruments not in dep: - continue - - req = Requirement(dep) - if req.marker.evaluate(instruments_marker): - instrumentation_deps.append(req) + if dist.requires: + for dep in dist.requires: + if extra not in dep or instruments not in dep: + continue + + req = Requirement(dep) + if req.marker.evaluate(instruments_marker): + instrumentation_deps.append(req) return get_dependency_conflicts(instrumentation_deps) diff --git a/opentelemetry-instrumentation/tests/test_dependencies.py b/opentelemetry-instrumentation/tests/test_dependencies.py index bdee0f6f01..ca04833181 100644 --- a/opentelemetry-instrumentation/tests/test_dependencies.py +++ b/opentelemetry-instrumentation/tests/test_dependencies.py @@ -86,3 +86,19 @@ def requires(self): str(conflict), 'DependencyConflict: requested: "test-pkg~=1.0; extra == "instruments"" but found: "None"', ) + + def test_get_dist_dependency_conflicts_requires_none(self): + class MockDistribution(Distribution): + def locate_file(self, path): + pass + + def read_text(self, filename): + pass + + @property + def requires(self): + return None + + dist = MockDistribution() + conflict = get_dist_dependency_conflicts(dist) + self.assertTrue(conflict is None) From 908437db5df522697f5504d44fc3d1fec56830be Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 9 Jan 2025 11:29:31 +0100 Subject: [PATCH 310/335] click: ignore click based servers (#3174) * click: ignore click based servers We don't want to create a root span for long running processes like servers otherwise all requests would have the same trace id which is unfortunate. --------- Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> --- CHANGELOG.md | 2 ++ .../instrumentation/click/__init__.py | 30 ++++++++++++++++++- .../test-requirements.txt | 9 ++++++ .../tests/test_click.py | 29 +++++++++++++++++- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80d63d0395..8c88a0243d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints ([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105)) +- `opentelemetry-instrumentation-click` Disable tracing of well-known server click commands + ([#3174](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3174)) - `opentelemetry-instrumentation` Fix `get_dist_dependency_conflicts` if no distribution requires ([#3168](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3168)) diff --git a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py index 8222bfdf5a..e820ca7d87 100644 --- a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/__init__.py @@ -13,7 +13,9 @@ # limitations under the License. """ -Instrument `click`_ CLI applications. +Instrument `click`_ CLI applications. The instrumentor will avoid instrumenting +well-known servers (e.g. *flask run* and *uvicorn*) to avoid unexpected effects +like every request having the same Trace ID. .. _click: https://pypi.org/project/click/ @@ -47,6 +49,12 @@ def hello(): import click from wrapt import wrap_function_wrapper +try: + from flask.cli import ScriptInfo as FlaskScriptInfo +except ImportError: + FlaskScriptInfo = None + + from opentelemetry import trace from opentelemetry.instrumentation.click.package import _instruments from opentelemetry.instrumentation.click.version import __version__ @@ -66,6 +74,20 @@ def hello(): _logger = getLogger(__name__) +def _skip_servers(ctx: click.Context): + # flask run + if ( + ctx.info_name == "run" + and FlaskScriptInfo + and isinstance(ctx.obj, FlaskScriptInfo) + ): + return True + # uvicorn + if ctx.info_name == "uvicorn": + return True + return False + + def _command_invoke_wrapper(wrapped, instance, args, kwargs, tracer): # Subclasses of Command include groups and CLI runners, but # we only want to instrument the actual commands which are @@ -74,6 +96,12 @@ def _command_invoke_wrapper(wrapped, instance, args, kwargs, tracer): return wrapped(*args, **kwargs) ctx = args[0] + + # we don't want to create a root span for long running processes like servers + # otherwise all requests would have the same trace id + if _skip_servers(ctx): + return wrapped(*args, **kwargs) + span_name = ctx.info_name span_attributes = { PROCESS_COMMAND_ARGS: sys.argv, diff --git a/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt index 6e9162ccde..e07bd05bb7 100644 --- a/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt @@ -1,7 +1,12 @@ asgiref==3.8.1 +blinker==1.7.0 click==8.1.7 Deprecated==1.2.14 +Flask==3.0.2 iniconfig==2.0.0 +itsdangerous==2.1.2 +Jinja2==3.1.4 +MarkupSafe==2.1.2 packaging==24.0 pluggy==1.5.0 py-cpuinfo==9.0.0 @@ -9,7 +14,11 @@ pytest==7.4.4 pytest-asyncio==0.23.5 tomli==2.0.1 typing_extensions==4.12.2 +Werkzeug==3.0.6 wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-click +-e instrumentation/opentelemetry-instrumentation-flask +-e instrumentation/opentelemetry-instrumentation-wsgi +-e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py b/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py index 41d01a5bb4..1b07f6ab56 100644 --- a/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py +++ b/instrumentation/opentelemetry-instrumentation-click/tests/test_click.py @@ -16,8 +16,14 @@ from unittest import mock import click +import pytest from click.testing import CliRunner +try: + from flask import cli as flask_cli +except ImportError: + flask_cli = None + from opentelemetry.instrumentation.click import ClickInstrumentor from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind @@ -60,7 +66,7 @@ def command(): ) @mock.patch("sys.argv", ["flask", "command"]) - def test_flask_run_command_wrapping(self): + def test_flask_command_wrapping(self): @click.command() def command(): pass @@ -162,6 +168,27 @@ def command_raises(): }, ) + def test_uvicorn_cli_command_ignored(self): + @click.command("uvicorn") + def command_uvicorn(): + pass + + runner = CliRunner() + result = runner.invoke(command_uvicorn) + self.assertEqual(result.exit_code, 0) + + self.assertFalse(self.memory_exporter.get_finished_spans()) + + @pytest.mark.skipif(flask_cli is None, reason="requires flask") + def test_flask_run_command_ignored(self): + runner = CliRunner() + result = runner.invoke( + flask_cli.run_command, obj=flask_cli.ScriptInfo() + ) + self.assertEqual(result.exit_code, 2) + + self.assertFalse(self.memory_exporter.get_finished_spans()) + def test_uninstrument(self): ClickInstrumentor().uninstrument() From 26bcc9347b76eb21f33e0491e4c152d61cbd2390 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:56:14 -0800 Subject: [PATCH 311/335] SQLAlchemy: db.statement inclusion of sqlcomment as opt-in (#3112) --- CHANGELOG.md | 4 + .../instrumentation/sqlalchemy/__init__.py | 44 +++- .../instrumentation/sqlalchemy/engine.py | 90 +++++--- .../tests/test_sqlalchemy.py | 182 ++++++++++++++++ .../tests/test_sqlcommenter.py | 206 +++++++++++++++++- 5 files changed, 497 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c88a0243d..d87091a2bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation` Fix `get_dist_dependency_conflicts` if no distribution requires ([#3168](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3168)) +### Breaking changes + +- `opentelemetry-instrumentation-sqlalchemy` including sqlcomment in `db.statement` span attribute value is now opt-in + ([#3112](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3112)) ## Version 1.29.0/0.50b0 (2024-12-11) diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py index 4182c0034e..23b68a6c52 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py @@ -65,6 +65,30 @@ :: Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ +SQLComment in span attribute +**************************** +If sqlcommenter is enabled, you can further configure SQLAlchemy instrumentation to append sqlcomment to the `db.statement` span attribute for convenience of your platform. + +.. code:: python + + from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor + + SQLAlchemyInstrumentor().instrument( + enable_commenter=True, + commenter_options={}, + enable_attribute_commenter=True, + ) + + +For example, +:: + + Invoking `engine.execute("select * from auth_users")` will lead to sql query "select * from auth_users" but when SQLCommenter and `attribute_commenter` is enabled + the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;" for both server query and `db.statement` span attribute. + +Warning: capture of sqlcomment in ``db.statement`` may have high cardinality without platform normalization. See `Semantic Conventions for database spans `_ for more information. + + Usage ----- .. code:: python @@ -138,6 +162,7 @@ def _instrument(self, **kwargs): ``meter_provider``: a MeterProvider, defaults to global ``enable_commenter``: bool to enable sqlcommenter, defaults to False ``commenter_options``: dict of sqlcommenter config, defaults to {} + ``enable_attribute_commenter``: bool to enable sqlcomment addition to span attribute, defaults to False. Must also set `enable_commenter`. Returns: An instrumented engine if passed in as an argument or list of instrumented engines, None otherwise. @@ -166,19 +191,30 @@ def _instrument(self, **kwargs): enable_commenter = kwargs.get("enable_commenter", False) commenter_options = kwargs.get("commenter_options", {}) + enable_attribute_commenter = kwargs.get( + "enable_attribute_commenter", False + ) _w( "sqlalchemy", "create_engine", _wrap_create_engine( - tracer, connections_usage, enable_commenter, commenter_options + tracer, + connections_usage, + enable_commenter, + commenter_options, + enable_attribute_commenter, ), ) _w( "sqlalchemy.engine", "create_engine", _wrap_create_engine( - tracer, connections_usage, enable_commenter, commenter_options + tracer, + connections_usage, + enable_commenter, + commenter_options, + enable_attribute_commenter, ), ) # sqlalchemy.engine.create is not present in earlier versions of sqlalchemy (which we support) @@ -191,6 +227,7 @@ def _instrument(self, **kwargs): connections_usage, enable_commenter, commenter_options, + enable_attribute_commenter, ), ) _w( @@ -207,6 +244,7 @@ def _instrument(self, **kwargs): connections_usage, enable_commenter, commenter_options, + enable_attribute_commenter, ), ) if kwargs.get("engine") is not None: @@ -216,6 +254,7 @@ def _instrument(self, **kwargs): connections_usage, kwargs.get("enable_commenter", False), kwargs.get("commenter_options", {}), + kwargs.get("enable_attribute_commenter", False), ) if kwargs.get("engines") is not None and isinstance( kwargs.get("engines"), Sequence @@ -227,6 +266,7 @@ def _instrument(self, **kwargs): connections_usage, kwargs.get("enable_commenter", False), kwargs.get("commenter_options", {}), + kwargs.get("enable_attribute_commenter", False), ) for engine in kwargs.get("engines") ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py index a20e481819..a3312bd77c 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py @@ -43,7 +43,11 @@ def _normalize_vendor(vendor): def _wrap_create_async_engine( - tracer, connections_usage, enable_commenter=False, commenter_options=None + tracer, + connections_usage, + enable_commenter=False, + commenter_options=None, + enable_attribute_commenter=False, ): # pylint: disable=unused-argument def _wrap_create_async_engine_internal(func, module, args, kwargs): @@ -57,6 +61,7 @@ def _wrap_create_async_engine_internal(func, module, args, kwargs): connections_usage, enable_commenter, commenter_options, + enable_attribute_commenter, ) return engine @@ -64,7 +69,11 @@ def _wrap_create_async_engine_internal(func, module, args, kwargs): def _wrap_create_engine( - tracer, connections_usage, enable_commenter=False, commenter_options=None + tracer, + connections_usage, + enable_commenter=False, + commenter_options=None, + enable_attribute_commenter=False, ): def _wrap_create_engine_internal(func, _module, args, kwargs): """Trace the SQLAlchemy engine, creating an `EngineTracer` @@ -77,6 +86,7 @@ def _wrap_create_engine_internal(func, _module, args, kwargs): connections_usage, enable_commenter, commenter_options, + enable_attribute_commenter, ) return engine @@ -110,12 +120,14 @@ def __init__( connections_usage, enable_commenter=False, commenter_options=None, + enable_attribute_commenter=False, ): self.tracer = tracer self.connections_usage = connections_usage self.vendor = _normalize_vendor(engine.name) self.enable_commenter = enable_commenter self.commenter_options = commenter_options if commenter_options else {} + self.enable_attribute_commenter = enable_attribute_commenter self._engine_attrs = _get_attributes_from_engine(engine) self._leading_comment_remover = re.compile(r"^/\*.*?\*/") @@ -218,6 +230,32 @@ def _operation_name(self, db_name, statement): return self.vendor return " ".join(parts) + def _get_commenter_data(self, conn) -> dict: + """Calculate sqlcomment contents from conn and configured options""" + commenter_data = { + "db_driver": conn.engine.driver, + # Driver/framework centric information. + "db_framework": f"sqlalchemy:{sqlalchemy.__version__}", + } + + if self.commenter_options.get("opentelemetry_values", True): + commenter_data.update(**_get_opentelemetry_values()) + + # Filter down to just the requested attributes. + commenter_data = { + k: v + for k, v in commenter_data.items() + if self.commenter_options.get(k, True) + } + return commenter_data + + def _set_db_client_span_attributes(self, span, statement, attrs) -> None: + """Uses statement and attrs to set attributes of provided Otel span""" + span.set_attribute(SpanAttributes.DB_STATEMENT, statement) + span.set_attribute(SpanAttributes.DB_SYSTEM, self.vendor) + for key, value in attrs.items(): + span.set_attribute(key, value) + def _before_cur_exec( self, conn, cursor, statement, params, context, _executemany ): @@ -233,30 +271,30 @@ def _before_cur_exec( with trace.use_span(span, end_on_exit=False): if span.is_recording(): if self.enable_commenter: - commenter_data = { - "db_driver": conn.engine.driver, - # Driver/framework centric information. - "db_framework": f"sqlalchemy:{sqlalchemy.__version__}", - } - - if self.commenter_options.get( - "opentelemetry_values", True - ): - commenter_data.update(**_get_opentelemetry_values()) - - # Filter down to just the requested attributes. - commenter_data = { - k: v - for k, v in commenter_data.items() - if self.commenter_options.get(k, True) - } - - statement = _add_sql_comment(statement, **commenter_data) - - span.set_attribute(SpanAttributes.DB_STATEMENT, statement) - span.set_attribute(SpanAttributes.DB_SYSTEM, self.vendor) - for key, value in attrs.items(): - span.set_attribute(key, value) + commenter_data = self._get_commenter_data(conn) + + if self.enable_attribute_commenter: + # sqlcomment is added to executed query and db.statement span attribute + statement = _add_sql_comment( + statement, **commenter_data + ) + self._set_db_client_span_attributes( + span, statement, attrs + ) + + else: + # sqlcomment is only added to executed query + # so db.statement is set before add_sql_comment + self._set_db_client_span_attributes( + span, statement, attrs + ) + statement = _add_sql_comment( + statement, **commenter_data + ) + + else: + # no sqlcomment anywhere + self._set_db_client_span_attributes(span, statement, attrs) context._otel_span = span diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py index 27a253decb..8f5d0f2a94 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py @@ -209,6 +209,44 @@ def test_create_engine_wrapper_enable_commenter(self): self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_create_engine_wrapper_enable_commenter_stmt_enabled(self): + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + SQLAlchemyInstrumentor().instrument( + enable_commenter=True, + commenter_options={"db_framework": False}, + enable_attribute_commenter=True, + ) + from sqlalchemy import create_engine # pylint: disable-all + + engine = create_engine("sqlite:///:memory:") + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + # sqlcommenter + self.assertRegex( + self.caplog.records[-2].getMessage(), + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_create_engine_wrapper_enable_commenter_otel_values_false(self): logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) @@ -229,6 +267,49 @@ def test_create_engine_wrapper_enable_commenter_otel_values_false(self): self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_create_engine_wrapper_enable_commenter_stmt_enabled_otel_values_false( + self, + ): + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + SQLAlchemyInstrumentor().instrument( + enable_commenter=True, + commenter_options={ + "db_framework": False, + "opentelemetry_values": False, + }, + enable_attribute_commenter=True, + ) + from sqlalchemy import create_engine # pylint: disable-all + + engine = create_engine("sqlite:///:memory:") + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + # sqlcommenter + self.assertRegex( + self.caplog.records[-2].getMessage(), + r"SELECT 1 /\*db_driver='(.*)'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)'\*/;", + ) def test_custom_tracer_provider(self): provider = TracerProvider( @@ -321,6 +402,55 @@ async def run(): self.caplog.records[1].getMessage(), r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + asyncio.get_event_loop().run_until_complete(run()) + + @pytest.mark.skipif( + not sqlalchemy.__version__.startswith("1.4"), + reason="only run async tests for 1.4", + ) + def test_create_async_engine_wrapper_enable_commenter_stmt_enabled(self): + async def run(): + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + SQLAlchemyInstrumentor().instrument( + enable_commenter=True, + commenter_options={ + "db_framework": False, + }, + enable_attribute_commenter=True, + ) + from sqlalchemy.ext.asyncio import ( # pylint: disable-all + create_async_engine, + ) + + engine = create_async_engine("sqlite+aiosqlite:///:memory:") + async with engine.connect() as cnx: + await cnx.execute(text("SELECT 1;")) + # sqlcommenter + self.assertRegex( + self.caplog.records[1].getMessage(), + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) asyncio.get_event_loop().run_until_complete(run()) @@ -352,6 +482,58 @@ async def run(): self.caplog.records[1].getMessage(), r"SELECT 1 /\*db_driver='(.*)'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + asyncio.get_event_loop().run_until_complete(run()) + + @pytest.mark.skipif( + not sqlalchemy.__version__.startswith("1.4"), + reason="only run async tests for 1.4", + ) + def test_create_async_engine_wrapper_enable_commenter_stmt_enabled_otel_values_false( + self, + ): + async def run(): + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + SQLAlchemyInstrumentor().instrument( + enable_commenter=True, + commenter_options={ + "db_framework": False, + "opentelemetry_values": False, + }, + enable_attribute_commenter=True, + ) + from sqlalchemy.ext.asyncio import ( # pylint: disable-all + create_async_engine, + ) + + engine = create_async_engine("sqlite+aiosqlite:///:memory:") + async with engine.connect() as cnx: + await cnx.execute(text("SELECT 1;")) + # sqlcommenter + self.assertRegex( + self.caplog.records[1].getMessage(), + r"SELECT 1 /\*db_driver='(.*)'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)'*/;", + ) asyncio.get_event_loop().run_until_complete(run()) diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py index 8490721e3e..d8144dadc1 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py @@ -61,13 +61,97 @@ def test_sqlcommenter_enabled(self): r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) - def test_sqlcommenter_enabled_matches_db_statement_attribute(self): + def test_sqlcommenter_default_stmt_enabled_no_comments_anywhere(self): + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + # enable_commenter not set + enable_attribute_commenter=True, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + query_log = self.caplog.records[-2].getMessage() + self.assertEqual( + query_log, + "SELECT 1;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_sqlcommenter_disabled_stmt_enabled_no_comments_anywhere(self): + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=False, + enable_attribute_commenter=True, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + query_log = self.caplog.records[-2].getMessage() + self.assertEqual( + query_log, + "SELECT 1;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_sqlcommenter_enabled_stmt_disabled_default( + self, + ): + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={"db_framework": False}, + # enable_attribute_commenter not set + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + query_log = self.caplog.records[-2].getMessage() + self.assertRegex( + query_log, + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_sqlcommenter_enabled_stmt_enabled_matches_db_statement_attribute( + self, + ): engine = create_engine("sqlite:///:memory:") SQLAlchemyInstrumentor().instrument( engine=engine, tracer_provider=self.tracer_provider, enable_commenter=True, commenter_options={"db_framework": False}, + enable_attribute_commenter=True, ) cnx = engine.connect() cnx.execute(text("SELECT 1;")).fetchall() @@ -110,6 +194,45 @@ def test_sqlcommenter_enabled_otel_values_false(self): self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1;", + ) + + def test_sqlcommenter_enabled_stmt_enabled_otel_values_false(self): + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={ + "db_framework": False, + "opentelemetry_values": False, + }, + enable_attribute_commenter=True, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + self.assertRegex( + self.caplog.records[-2].getMessage(), + r"SELECT 1 /\*db_driver='(.*)'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)'*/;", + ) def test_sqlcommenter_flask_integration(self): engine = create_engine("sqlite:///:memory:") @@ -132,6 +255,49 @@ def test_sqlcommenter_flask_integration(self): self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)',flask=1,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_sqlcommenter_stmt_enabled_flask_integration(self): + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={"db_framework": False}, + enable_attribute_commenter=True, + ) + cnx = engine.connect() + + current_context = context.get_current() + sqlcommenter_context = context.set_value( + "SQLCOMMENTER_ORM_TAGS_AND_VALUES", {"flask": 1}, current_context + ) + context.attach(sqlcommenter_context) + + cnx.execute(text("SELECT 1;")).fetchall() + self.assertRegex( + self.caplog.records[-2].getMessage(), + r"SELECT 1 /\*db_driver='(.*)',flask=1,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)',flask=1,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_sqlcommenter_enabled_create_engine_after_instrumentation(self): SQLAlchemyInstrumentor().instrument( @@ -147,6 +313,44 @@ def test_sqlcommenter_enabled_create_engine_after_instrumentation(self): self.caplog.records[-2].getMessage(), r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertEqual( + query_span.attributes[SpanAttributes.DB_STATEMENT], + "SELECT 1;", + ) + + def test_sqlcommenter_enabled_stmt_enabled_create_engine_after_instrumentation( + self, + ): + SQLAlchemyInstrumentor().instrument( + tracer_provider=self.tracer_provider, + enable_commenter=True, + enable_attribute_commenter=True, + ) + from sqlalchemy import create_engine # pylint: disable-all + + engine = create_engine("sqlite:///:memory:") + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + self.assertRegex( + self.caplog.records[-2].getMessage(), + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + # first span is connection to db + self.assertEqual(spans[0].name, "connect") + # second span is query itself + query_span = spans[1] + self.assertRegex( + query_span.attributes[SpanAttributes.DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_sqlcommenter_disabled_create_engine_after_instrumentation(self): SQLAlchemyInstrumentor().instrument( From cf6d45e96cd1ea55fca2ff43dc37f0d5c8c878fc Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:08:46 -0800 Subject: [PATCH 312/335] DB-API: db.statement inclusion of sqlcomment as opt-in (#3115) --- CHANGELOG.md | 6 + .../instrumentation/dbapi/__init__.py | 112 +++-- .../tests/test_dbapi_integration.py | 406 +++++++++++++++++- 3 files changed, 479 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d87091a2bb..47965fc581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-sqlalchemy` including sqlcomment in `db.statement` span attribute value is now opt-in ([#3112](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3112)) +### Breaking changes + +- `opentelemetry-instrumentation-dbapi` including sqlcomment in `db.statement` span attribute value is now opt-in + ([#3115](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3115)) + + ## Version 1.29.0/0.50b0 (2024-12-11) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index d8db967f47..9b709c584c 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -71,6 +71,7 @@ def trace_integration( capture_parameters: bool = False, enable_commenter: bool = False, db_api_integration_factory=None, + enable_attribute_commenter: bool = False, ): """Integrate with DB API library. https://www.python.org/dev/peps/pep-0249/ @@ -88,6 +89,7 @@ def trace_integration( enable_commenter: Flag to enable/disable sqlcommenter. db_api_integration_factory: The `DatabaseApiIntegration` to use. If none is passed the default one is used. + enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True. """ wrap_connect( __name__, @@ -100,6 +102,7 @@ def trace_integration( capture_parameters=capture_parameters, enable_commenter=enable_commenter, db_api_integration_factory=db_api_integration_factory, + enable_attribute_commenter=enable_attribute_commenter, ) @@ -115,6 +118,7 @@ def wrap_connect( enable_commenter: bool = False, db_api_integration_factory=None, commenter_options: dict = None, + enable_attribute_commenter: bool = False, ): """Integrate with DB API library. https://www.python.org/dev/peps/pep-0249/ @@ -133,6 +137,7 @@ def wrap_connect( db_api_integration_factory: The `DatabaseApiIntegration` to use. If none is passed the default one is used. commenter_options: Configurations for tags to be appended at the sql query. + enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True. """ db_api_integration_factory = ( @@ -156,6 +161,7 @@ def wrap_connect_( enable_commenter=enable_commenter, commenter_options=commenter_options, connect_module=connect_module, + enable_attribute_commenter=enable_attribute_commenter, ) return db_integration.wrapped_connection(wrapped, args, kwargs) @@ -191,6 +197,7 @@ def instrument_connection( enable_commenter: bool = False, commenter_options: dict = None, connect_module: typing.Callable[..., typing.Any] = None, + enable_attribute_commenter: bool = False, ): """Enable instrumentation in a database connection. @@ -206,6 +213,7 @@ def instrument_connection( enable_commenter: Flag to enable/disable sqlcommenter. commenter_options: Configurations for tags to be appended at the sql query. connect_module: Module name where connect method is available. + enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True. Returns: An instrumented connection. @@ -224,6 +232,7 @@ def instrument_connection( enable_commenter=enable_commenter, commenter_options=commenter_options, connect_module=connect_module, + enable_attribute_commenter=enable_attribute_commenter, ) db_integration.get_connection_attributes(connection) return get_traced_connection_proxy(connection, db_integration) @@ -257,6 +266,7 @@ def __init__( enable_commenter: bool = False, commenter_options: dict = None, connect_module: typing.Callable[..., typing.Any] = None, + enable_attribute_commenter: bool = False, ): self.connection_attributes = connection_attributes if self.connection_attributes is None: @@ -277,6 +287,7 @@ def __init__( self.capture_parameters = capture_parameters self.enable_commenter = enable_commenter self.commenter_options = commenter_options + self.enable_attribute_commenter = enable_attribute_commenter self.database_system = database_system self.connection_props = {} self.span_attributes = {} @@ -434,9 +445,52 @@ def __init__(self, db_api_integration: DatabaseApiIntegration) -> None: if self._db_api_integration.commenter_options else {} ) + self._enable_attribute_commenter = ( + self._db_api_integration.enable_attribute_commenter + ) self._connect_module = self._db_api_integration.connect_module self._leading_comment_remover = re.compile(r"^/\*.*?\*/") + def _capture_mysql_version(self, cursor) -> None: + """Lazy capture of mysql-connector client version using cursor, if applicable""" + if ( + self._db_api_integration.database_system == "mysql" + and self._db_api_integration.connect_module.__name__ + == "mysql.connector" + and not self._db_api_integration.commenter_data[ + "mysql_client_version" + ] + ): + self._db_api_integration.commenter_data["mysql_client_version"] = ( + cursor._cnx._cmysql.get_client_info() + ) + + def _get_commenter_data(self) -> dict: + """Uses DB-API integration to return commenter data for sqlcomment""" + commenter_data = dict(self._db_api_integration.commenter_data) + if self._commenter_options.get("opentelemetry_values", True): + commenter_data.update(**_get_opentelemetry_values()) + return { + k: v + for k, v in commenter_data.items() + if self._commenter_options.get(k, True) + } + + def _update_args_with_added_sql_comment(self, args, cursor) -> tuple: + """Updates args with cursor info and adds sqlcomment to query statement""" + try: + args_list = list(args) + self._capture_mysql_version(cursor) + commenter_data = self._get_commenter_data() + statement = _add_sql_comment(args_list[0], **commenter_data) + args_list[0] = statement + args = tuple(args_list) + except Exception as exc: # pylint: disable=broad-except + _logger.exception( + "Exception while generating sql comment: %s", exc + ) + return args + def _populate_span( self, span: trace_api.Span, @@ -497,52 +551,22 @@ def traced_execution( ) as span: if span.is_recording(): if args and self._commenter_enabled: - try: - args_list = list(args) - - # lazy capture of mysql-connector client version using cursor - if ( - self._db_api_integration.database_system == "mysql" - and self._db_api_integration.connect_module.__name__ - == "mysql.connector" - and not self._db_api_integration.commenter_data[ - "mysql_client_version" - ] - ): - self._db_api_integration.commenter_data[ - "mysql_client_version" - ] = cursor._cnx._cmysql.get_client_info() - - commenter_data = dict( - self._db_api_integration.commenter_data - ) - if self._commenter_options.get( - "opentelemetry_values", True - ): - commenter_data.update( - **_get_opentelemetry_values() - ) - - # Filter down to just the requested attributes. - commenter_data = { - k: v - for k, v in commenter_data.items() - if self._commenter_options.get(k, True) - } - statement = _add_sql_comment( - args_list[0], **commenter_data + if self._enable_attribute_commenter: + # sqlcomment is added to executed query and db.statement span attribute + args = self._update_args_with_added_sql_comment( + args, cursor ) - - args_list[0] = statement - args = tuple(args_list) - - except Exception as exc: # pylint: disable=broad-except - _logger.exception( - "Exception while generating sql comment: %s", exc + self._populate_span(span, cursor, *args) + else: + # sqlcomment is only added to executed query + # so db.statement is set before add_sql_comment + self._populate_span(span, cursor, *args) + args = self._update_args_with_added_sql_comment( + args, cursor ) - - self._populate_span(span, cursor, *args) - + else: + # no sqlcomment anywhere + self._populate_span(span, cursor, *args) return query_method(*args, **kwargs) diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index 2ffa2f3d5b..3d531fb791 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=too-many-lines import logging import re @@ -277,6 +278,47 @@ def test_executemany_comment(self): cursor.query, r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_executemany_comment_stmt_enabled(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "test" + connect_module.__version__ = mock.MagicMock() + connect_module.__libpq_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": False, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_executemany_comment_non_pep_249_compliant(self): class MockConnectModule: @@ -306,8 +348,54 @@ def __getattr__(self, name): cursor.query, r"Select 1 /\*dbapi_level='1.0',dbapi_threadsafety='unknown',driver_paramstyle='unknown',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) - def test_executemany_comment_matches_db_statement_attribute(self): + def test_executemany_comment_non_pep_249_compliant_stmt_enabled(self): + class MockConnectModule: + def __getattr__(self, name): + if name == "__name__": + return "test" + if name == "__version__": + return mock.MagicMock() + if name == "__libpq_version__": + return 123 + raise AttributeError("attribute missing") + + connect_module = MockConnectModule() + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + connect_module=connect_module, + commenter_options={"db_driver": False}, + enable_attribute_commenter=True, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_level='1.0',dbapi_threadsafety='unknown',driver_paramstyle='unknown',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*dbapi_level='1.0',dbapi_threadsafety='unknown',driver_paramstyle='unknown',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + + def test_executemany_comment_stmt_enabled_matches_db_statement_attribute( + self, + ): connect_module = mock.MagicMock() connect_module.__version__ = mock.MagicMock() connect_module.__libpq_version__ = 123 @@ -321,6 +409,7 @@ def test_executemany_comment_matches_db_statement_attribute(self): enable_commenter=True, commenter_options={"db_driver": False, "dbapi_level": False}, connect_module=connect_module, + enable_attribute_commenter=True, ) mock_connection = db_integration.wrapped_connection( mock_connect, {}, {} @@ -371,6 +460,50 @@ def test_compatible_build_version_psycopg_psycopg2_libpq(self): cursor.query, r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_compatible_build_version_psycopg_psycopg2_libpq_stmt_enabled( + self, + ): + connect_module = mock.MagicMock() + connect_module.__name__ = "test" + connect_module.__version__ = mock.MagicMock() + connect_module.pq = mock.MagicMock() + connect_module.pq.__build_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": False, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_executemany_psycopg2_integration_comment(self): connect_module = mock.MagicMock() @@ -397,6 +530,47 @@ def test_executemany_psycopg2_integration_comment(self): cursor.query, r"Select 1 /\*db_driver='psycopg2%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_executemany_psycopg2_integration_comment_stmt_enabled(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "psycopg2" + connect_module.__version__ = "1.2.3" + connect_module.__libpq_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='psycopg2%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*db_driver='psycopg2%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_executemany_psycopg_integration_comment(self): connect_module = mock.MagicMock() @@ -424,6 +598,48 @@ def test_executemany_psycopg_integration_comment(self): cursor.query, r"Select 1 /\*db_driver='psycopg%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_executemany_psycopg_integration_comment_stmt_enabled(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "psycopg" + connect_module.__version__ = "1.2.3" + connect_module.pq = mock.MagicMock() + connect_module.pq.__build_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='psycopg%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*db_driver='psycopg%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_executemany_mysqlconnector_integration_comment(self): connect_module = mock.MagicMock() @@ -450,6 +666,47 @@ def test_executemany_mysqlconnector_integration_comment(self): cursor.query, r"Select 1 /\*db_driver='mysql.connector%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='1.2.3',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_executemany_mysqlconnector_integration_comment_stmt_enabled(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "mysql.connector" + connect_module.__version__ = "1.2.3" + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "mysql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='mysql.connector%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='1.2.3',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*db_driver='mysql.connector%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='1.2.3',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) @mock.patch("opentelemetry.instrumentation.dbapi.util_version") def test_executemany_mysqlclient_integration_comment( @@ -485,6 +742,56 @@ def test_executemany_mysqlclient_integration_comment( cursor.query, r"Select 1 /\*db_driver='MySQLdb%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + @mock.patch("opentelemetry.instrumentation.dbapi.util_version") + def test_executemany_mysqlclient_integration_comment_stmt_enabled( + self, + mock_dbapi_util_version, + ): + mock_dbapi_util_version.return_value = "1.2.3" + connect_module = mock.MagicMock() + connect_module.__name__ = "MySQLdb" + connect_module.__version__ = "1.2.3" + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + connect_module._mysql = mock.MagicMock() + connect_module._mysql.get_client_info = mock.MagicMock( + return_value="123" + ) + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "mysql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='MySQLdb%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*db_driver='MySQLdb%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_executemany_pymysql_integration_comment(self): connect_module = mock.MagicMock() @@ -512,6 +819,48 @@ def test_executemany_pymysql_integration_comment(self): cursor.query, r"Select 1 /\*db_driver='pymysql%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_executemany_pymysql_integration_comment_stmt_enabled(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "pymysql" + connect_module.__version__ = "1.2.3" + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + connect_module.get_client_info = mock.MagicMock(return_value="123") + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "mysql", + enable_commenter=True, + commenter_options={"db_driver": True, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*db_driver='pymysql%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*db_driver='pymysql%%3A1.2.3',dbapi_threadsafety=123,driver_paramstyle='test',mysql_client_version='123',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) def test_executemany_flask_integration_comment(self): connect_module = mock.MagicMock() @@ -544,6 +893,58 @@ def test_executemany_flask_integration_comment(self): cursor.query, r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',flask=1,libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + clear_context = context.set_value( + "SQLCOMMENTER_ORM_TAGS_AND_VALUES", {}, current_context + ) + context.attach(clear_context) + + def test_executemany_flask_integration_comment_stmt_enabled(self): + connect_module = mock.MagicMock() + connect_module.__name__ = "test" + connect_module.__version__ = mock.MagicMock() + connect_module.__libpq_version__ = 123 + connect_module.apilevel = 123 + connect_module.threadsafety = 123 + connect_module.paramstyle = "test" + + db_integration = dbapi.DatabaseApiIntegration( + "testname", + "postgresql", + enable_commenter=True, + commenter_options={"db_driver": False, "dbapi_level": False}, + connect_module=connect_module, + enable_attribute_commenter=True, + ) + current_context = context.get_current() + sqlcommenter_context = context.set_value( + "SQLCOMMENTER_ORM_TAGS_AND_VALUES", {"flask": 1}, current_context + ) + context.attach(sqlcommenter_context) + + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + cursor.executemany("Select 1;") + self.assertRegex( + cursor.query, + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',flask=1,libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertRegex( + span.attributes[SpanAttributes.DB_STATEMENT], + r"Select 1 /\*dbapi_threadsafety=123,driver_paramstyle='test',flask=1,libpq_version=123,traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) clear_context = context.set_value( "SQLCOMMENTER_ORM_TAGS_AND_VALUES", {}, current_context @@ -603,6 +1004,7 @@ def test_instrument_connection_kwargs_defaults(self, mock_dbapiint): self.assertEqual(kwargs["enable_commenter"], False) self.assertEqual(kwargs["commenter_options"], None) self.assertEqual(kwargs["connect_module"], None) + self.assertEqual(kwargs["enable_attribute_commenter"], False) @mock.patch("opentelemetry.instrumentation.dbapi.DatabaseApiIntegration") def test_instrument_connection_kwargs_provided(self, mock_dbapiint): @@ -619,6 +1021,7 @@ def test_instrument_connection_kwargs_provided(self, mock_dbapiint): enable_commenter=True, commenter_options={"foo": "bar"}, connect_module=mock_connect_module, + enable_attribute_commenter=True, ) kwargs = mock_dbapiint.call_args[1] self.assertEqual(kwargs["connection_attributes"], {"foo": "bar"}) @@ -628,6 +1031,7 @@ def test_instrument_connection_kwargs_provided(self, mock_dbapiint): self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": "bar"}) self.assertIs(kwargs["connect_module"], mock_connect_module) + self.assertEqual(kwargs["enable_attribute_commenter"], True) def test_uninstrument_connection(self): connection = mock.Mock() From 9af3136e7fe21af88499621512cb22a77ee9b489 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Thu, 9 Jan 2025 22:21:19 +0100 Subject: [PATCH 313/335] Support PEP 561 to `opentelemetry-util-http` (#3127) --- CHANGELOG.md | 2 + .../src/opentelemetry/util/http/__init__.py | 14 +++---- .../src/opentelemetry/util/http/httplib.py | 42 +++++++++++++------ .../src/opentelemetry/util/http/py.typed | 0 4 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 util/opentelemetry-util-http/src/opentelemetry/util/http/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 47965fc581..9a35e342df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3148](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3148)) - add support to Python 3.13 ([#3134](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3134)) +- `opentelemetry-util-http` Add `py.typed` file to enable PEP 561 + ([#3127](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3127)) ### Fixed diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index f5dacf0fff..c7dd9f7b06 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -19,7 +19,7 @@ from re import IGNORECASE as RE_IGNORECASE from re import compile as re_compile from re import search -from typing import Callable, Iterable, Optional +from typing import Callable, Iterable from urllib.parse import urlparse, urlunparse from opentelemetry.semconv.trace import SpanAttributes @@ -121,18 +121,16 @@ def sanitize_header_values( _root = r"OTEL_PYTHON_{}" -def get_traced_request_attrs(instrumentation): +def get_traced_request_attrs(instrumentation: str) -> list[str]: traced_request_attrs = environ.get( - _root.format(f"{instrumentation}_TRACED_REQUEST_ATTRS"), [] + _root.format(f"{instrumentation}_TRACED_REQUEST_ATTRS") ) - if traced_request_attrs: - traced_request_attrs = [ + return [ traced_request_attr.strip() for traced_request_attr in traced_request_attrs.split(",") ] - - return traced_request_attrs + return [] def get_excluded_urls(instrumentation: str) -> ExcludeList: @@ -193,7 +191,7 @@ def normalise_response_header_name(header: str) -> str: return f"http.response.header.{key}" -def sanitize_method(method: Optional[str]) -> Optional[str]: +def sanitize_method(method: str | None) -> str | None: if method is None: return None method = method.upper() diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py index 3d6b875752..f375e2f7c8 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py @@ -17,12 +17,14 @@ not create spans on its own. """ +from __future__ import annotations + import contextlib import http.client import logging import socket # pylint:disable=unused-import # Used for typing import typing -from typing import Collection +from typing import Any, Callable, Collection, TypedDict, cast import wrapt @@ -36,20 +38,22 @@ logger = logging.getLogger(__name__) +R = typing.TypeVar("R") + class HttpClientInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return () # This instruments http.client from stdlib; no extra deps. - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Instruments the http.client module (not creating spans on its own)""" _instrument() - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): _uninstrument() -def _remove_nonrecording(spanlist: typing.List[Span]): +def _remove_nonrecording(spanlist: list[Span]) -> bool: idx = len(spanlist) - 1 while idx >= 0: if not spanlist[idx].is_recording(): @@ -67,7 +71,9 @@ def _remove_nonrecording(spanlist: typing.List[Span]): return True -def trysetip(conn: http.client.HTTPConnection, loglevel=logging.DEBUG) -> bool: +def trysetip( + conn: http.client.HTTPConnection, loglevel: int = logging.DEBUG +) -> bool: """Tries to set the net.peer.ip semantic attribute on the current span from the given HttpConnection. @@ -110,14 +116,17 @@ def trysetip(conn: http.client.HTTPConnection, loglevel=logging.DEBUG) -> bool: def _instrumented_connect( - wrapped, instance: http.client.HTTPConnection, args, kwargs -): + wrapped: Callable[..., R], + instance: http.client.HTTPConnection, + args: tuple[Any, ...], + kwargs: dict[str, Any], +) -> R: result = wrapped(*args, **kwargs) trysetip(instance, loglevel=logging.WARNING) return result -def instrument_connect(module, name="connect"): +def instrument_connect(module: type[Any], name: str = "connect"): """Instrument additional connect() methods, e.g. for derived classes.""" wrapt.wrap_function_wrapper( @@ -129,8 +138,11 @@ def instrument_connect(module, name="connect"): def _instrument(): def instrumented_send( - wrapped, instance: http.client.HTTPConnection, args, kwargs - ): + wrapped: Callable[..., R], + instance: http.client.HTTPConnection, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> R: done = trysetip(instance) result = wrapped(*args, **kwargs) if not done: @@ -147,8 +159,12 @@ def instrumented_send( # No need to instrument HTTPSConnection, as it calls super().connect() -def _getstate() -> typing.Optional[dict]: - return context.get_value(_STATE_KEY) +class _ConnectionState(TypedDict): + need_ip: list[Span] + + +def _getstate() -> _ConnectionState | None: + return cast(_ConnectionState, context.get_value(_STATE_KEY)) @contextlib.contextmanager @@ -163,7 +179,7 @@ def set_ip_on_next_http_connection(span: Span): finally: context.detach(token) else: - spans: typing.List[Span] = state["need_ip"] + spans = state["need_ip"] spans.append(span) try: yield diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/py.typed b/util/opentelemetry-util-http/src/opentelemetry/util/http/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 41e670aeee5c34c5104fa80aeb97a81976d19a5c Mon Sep 17 00:00:00 2001 From: Guspan Tanadi <36249910+guspan-tanadi@users.noreply.github.com> Date: Fri, 10 Jan 2025 04:58:53 +0700 Subject: [PATCH 314/335] docs(README): semantic convention migration links (#3160) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8582c472ba..2400e5d47a 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ The Python auto-instrumentation libraries for [OpenTelemetry](https://openteleme * [Installation](#installation) * [Releasing](#releasing) * [Releasing a package as `1.0` stable](#releasing-a-package-as-10-stable) +* [Semantic Convention status of instrumentations](#semantic-convention-status-of-instrumentations) * [Contributing](#contributing) * [Thanks to all the people who already contributed](#thanks-to-all-the-people-who-already-contributed) @@ -100,7 +101,7 @@ To release a package as `1.0` stable, the package: ## Semantic Convention status of instrumentations -In our efforts to maintain optimal user experience and prevent breaking changes for transitioning into stable semantic conventions, OpenTelemetry Python is adopting the [semantic convention migration plan](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/migration-guide.md) for several instrumentations. Currently this plan is only being adopted for HTTP-related instrumentations, but will eventually cover all types. Please refer to the `semconv status` column of the [instrumentation README](instrumentation/README.md) of the current status of instrumentations' semantic conventions. The possible values are `experimental`, `stable` and `migration` referring to [status](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.31.0/specification/document-status.md#lifecycle-status) of that particular semantic convention. `Migration` refers to an instrumentation that currently supports the migration plan. +In our efforts to maintain optimal user experience and prevent breaking changes for transitioning into stable semantic conventions, OpenTelemetry Python is adopting the semantic convention migration plan for several instrumentations. Currently this plan is only being adopted for [HTTP-related instrumentations](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md), but will eventually cover all types. Please refer to the `semconv status` column of the [instrumentation README](instrumentation/README.md) of the current status of instrumentations' semantic conventions. The possible values are `experimental`, `stable` and `migration` referring to [status](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.31.0/specification/document-status.md#lifecycle-status) of that particular semantic convention. `Migration` refers to an instrumentation that currently supports the migration plan. ## Contributing From 962a3aecdb3cd99bc0590303106be27c098a71f8 Mon Sep 17 00:00:00 2001 From: Will Li Date: Fri, 10 Jan 2025 06:51:23 +0800 Subject: [PATCH 315/335] fix #991 audit asyncpg instrumentation with nooptracerprovider (#3144) --- .../tests/test_asyncpg_wrapper.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py index 7c88b9c005..0fc44d6a23 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py @@ -5,6 +5,7 @@ from asyncpg import Connection, Record, cursor from wrapt import ObjectProxy +from opentelemetry import trace as trace_api from opentelemetry.instrumentation.asyncpg import AsyncPGInstrumentor from opentelemetry.test.test_base import TestBase @@ -105,3 +106,36 @@ async def exec_mock(*args, **kwargs): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) self.assertEqual([span.status.is_ok for span in spans], [True, True]) + + def test_no_op_tracer_provider(self): + AsyncPGInstrumentor().uninstrument() + AsyncPGInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + # Mock out all interaction with postgres + async def bind_mock(*args, **kwargs): + return [] + + async def exec_mock(*args, **kwargs): + return [], None, True + + conn = mock.Mock() + conn.is_closed = lambda: False + + conn._protocol = mock.Mock() + conn._protocol.bind = bind_mock + conn._protocol.execute = exec_mock + conn._protocol.bind_execute = exec_mock + conn._protocol.close_portal = bind_mock + + state = mock.Mock() + state.closed = False + + # init the cursor and fetch a single record + crs = cursor.Cursor(conn, "SELECT * FROM test", state, [], Record) + asyncio.run(crs._init(1)) + asyncio.run(crs.fetch(1)) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) From 0ad779a5b3d817111fc65099d1b849995365f4ee Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 10 Jan 2025 02:42:12 +0100 Subject: [PATCH 316/335] Support PEP 561 to `opentelemetry-instrumentation-jinja2` (#3137) --- .../instrumentation/jinja2/__init__.py | 57 +++++++++++++++---- .../instrumentation/jinja2/py.typed | 0 2 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/py.typed diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/__init__.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/__init__.py index 0b199cbe64..9867992d49 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/__init__.py @@ -39,17 +39,21 @@ """ # pylint: disable=no-value-for-parameter +from __future__ import annotations + import logging -from typing import Collection +from types import CodeType +from typing import Any, Callable, Collection, TypeVar import jinja2 +from jinja2.environment import Template from wrapt import wrap_function_wrapper as _wrap from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.jinja2.package import _instruments from opentelemetry.instrumentation.jinja2.version import __version__ from opentelemetry.instrumentation.utils import unwrap -from opentelemetry.trace import SpanKind, get_tracer +from opentelemetry.trace import SpanKind, Tracer, get_tracer logger = logging.getLogger(__name__) @@ -57,12 +61,27 @@ ATTRIBUTE_JINJA2_TEMPLATE_PATH = "jinja2.template_path" DEFAULT_TEMPLATE_NAME = "" +R = TypeVar("R") + -def _with_tracer_wrapper(func): +def _with_tracer_wrapper( + func: Callable[ + [Tracer, Callable[..., R], Any, list[Any], dict[str, Any]], R + ], +) -> Callable[ + [Tracer], Callable[[Callable[..., R], Any, list[Any], dict[str, Any]], R] +]: """Helper for providing tracer for wrapper functions.""" - def _with_tracer(tracer): - def wrapper(wrapped, instance, args, kwargs): + def _with_tracer( + tracer: Tracer, + ) -> Callable[[Callable[..., R], Any, list[Any], dict[str, Any]], R]: + def wrapper( + wrapped: Callable[..., R], + instance: Any, + args: list[Any], + kwargs: dict[str, Any], + ) -> R: return func(tracer, wrapped, instance, args, kwargs) return wrapper @@ -71,7 +90,13 @@ def wrapper(wrapped, instance, args, kwargs): @_with_tracer_wrapper -def _wrap_render(tracer, wrapped, instance, args, kwargs): +def _wrap_render( + tracer: Tracer, + wrapped: Callable[..., Any], + instance: Template, + args: list[Any], + kwargs: dict[str, Any], +): """Wrap `Template.render()` or `Template.generate()`""" with tracer.start_as_current_span( "jinja2.render", @@ -84,7 +109,13 @@ def _wrap_render(tracer, wrapped, instance, args, kwargs): @_with_tracer_wrapper -def _wrap_compile(tracer, wrapped, _, args, kwargs): +def _wrap_compile( + tracer: Tracer, + wrapped: Callable[..., CodeType], + _, + args: list[Any], + kwargs: dict[str, Any], +) -> CodeType: with tracer.start_as_current_span( "jinja2.compile", kind=SpanKind.INTERNAL, @@ -100,7 +131,13 @@ def _wrap_compile(tracer, wrapped, _, args, kwargs): @_with_tracer_wrapper -def _wrap_load_template(tracer, wrapped, _, args, kwargs): +def _wrap_load_template( + tracer: Tracer, + wrapped: Callable[..., Template], + _, + args: list[Any], + kwargs: dict[str, Any], +) -> Template: with tracer.start_as_current_span( "jinja2.load", kind=SpanKind.INTERNAL, @@ -128,7 +165,7 @@ class Jinja2Instrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): tracer_provider = kwargs.get("tracer_provider") tracer = get_tracer( __name__, @@ -146,7 +183,7 @@ def _instrument(self, **kwargs): _wrap_load_template(tracer), ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): unwrap(jinja2.Template, "render") unwrap(jinja2.Template, "generate") unwrap(jinja2.Environment, "compile") diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/py.typed b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/py.typed new file mode 100644 index 0000000000..e69de29bb2 From a606fab84901b9e2c1feab6167f36260c60dca6d Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 10 Jan 2025 18:00:10 +0100 Subject: [PATCH 317/335] Support PEP 561 to `opentelemetry-instrumentation-requests` (#3135) --- CHANGELOG.md | 2 ++ .../instrumentation/requests/__init__.py | 20 +++++++++++-------- .../instrumentation/requests/py.typed | 0 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a35e342df..3c35391e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) +- `opentelemetry-opentelemetry-requests` Add `py.typed` file to enable PEP 561 + ([#3135](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3135)) - `opentelemetry-instrumentation-system-metrics` Add `py.typed` file to enable PEP 561 ([#3132](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3132)) - `opentelemetry-opentelemetry-sqlite3` Add `py.typed` file to enable PEP 561 diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index d1afa834d6..6c197d530e 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -72,10 +72,12 @@ def response_hook(span, request_obj, response) --- """ +from __future__ import annotations + import functools import types from timeit import default_timer -from typing import Callable, Collection, Optional +from typing import Any, Callable, Collection, Optional from urllib.parse import urlparse from requests.models import PreparedRequest, Response @@ -146,7 +148,7 @@ def _instrument( duration_histogram_new: Histogram, request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, - excluded_urls: ExcludeList = None, + excluded_urls: ExcludeList | None = None, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): """Enables tracing of all requests calls that go through @@ -164,7 +166,9 @@ def _instrument( # pylint: disable-msg=too-many-locals,too-many-branches @functools.wraps(wrapped_send) - def instrumented_send(self, request, **kwargs): + def instrumented_send( + self: Session, request: PreparedRequest, **kwargs: Any + ): if excluded_urls and excluded_urls.url_disabled(request.url): return wrapped_send(self, request, **kwargs) @@ -345,7 +349,7 @@ def _uninstrument(): _uninstrument_from(Session) -def _uninstrument_from(instr_root, restore_as_bound_func=False): +def _uninstrument_from(instr_root, restore_as_bound_func: bool = False): for instr_func_name in ("request", "send"): instr_func = getattr(instr_root, instr_func_name) if not getattr( @@ -361,7 +365,7 @@ def _uninstrument_from(instr_root, restore_as_bound_func=False): setattr(instr_root, instr_func_name, original) -def get_default_span_name(method): +def get_default_span_name(method: str) -> str: """ Default implementation for name_callback, returns HTTP {method_name}. https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#name @@ -385,7 +389,7 @@ class RequestsInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Instruments requests module Args: @@ -443,10 +447,10 @@ def _instrument(self, **kwargs): sem_conv_opt_in_mode=semconv_opt_in_mode, ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): _uninstrument() @staticmethod - def uninstrument_session(session): + def uninstrument_session(session: Session): """Disables instrumentation on the session object.""" _uninstrument_from(session, restore_as_bound_func=True) diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/py.typed b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 3ebdb6344b81cccc933df7f979d0c9b92e18964a Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 10 Jan 2025 18:20:28 +0100 Subject: [PATCH 318/335] Support PEP 561 to `opentelemetry-instrumentation-pymongo` (#3136) --- CHANGELOG.md | 2 ++ .../instrumentation/pymongo/__init__.py | 33 +++++++++++++------ .../instrumentation/pymongo/py.typed | 0 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c35391e8e..a6d7340c8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) +- `opentelemetry-opentelemetry-pymongo` Add `py.typed` file to enable PEP 561 + ([#3136](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3136)) - `opentelemetry-opentelemetry-requests` Add `py.typed` file to enable PEP 561 ([#3135](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3135)) - `opentelemetry-instrumentation-system-metrics` Add `py.typed` file to enable PEP 561 diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py index e0721f2f2d..bb609a08c6 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py @@ -75,8 +75,10 @@ def failed_hook(span, event): """ +from __future__ import annotations + from logging import getLogger -from typing import Callable, Collection +from typing import Any, Callable, Collection, TypeVar from pymongo import monitoring @@ -88,7 +90,7 @@ def failed_hook(span, event): from opentelemetry.instrumentation.pymongo.version import __version__ from opentelemetry.instrumentation.utils import is_instrumentation_enabled from opentelemetry.semconv.trace import DbSystemValues, SpanAttributes -from opentelemetry.trace import SpanKind, get_tracer +from opentelemetry.trace import SpanKind, Tracer, get_tracer from opentelemetry.trace.span import Span from opentelemetry.trace.status import Status, StatusCode @@ -98,14 +100,21 @@ def failed_hook(span, event): ResponseHookT = Callable[[Span, monitoring.CommandSucceededEvent], None] FailedHookT = Callable[[Span, monitoring.CommandFailedEvent], None] +CommandEvent = TypeVar( + "CommandEvent", + monitoring.CommandStartedEvent, + monitoring.CommandSucceededEvent, + monitoring.CommandFailedEvent, +) + -def dummy_callback(span, event): ... +def dummy_callback(span: Span, event: CommandEvent): ... class CommandTracer(monitoring.CommandListener): def __init__( self, - tracer, + tracer: Tracer, request_hook: RequestHookT = dummy_callback, response_hook: ResponseHookT = dummy_callback, failed_hook: FailedHookT = dummy_callback, @@ -195,10 +204,12 @@ def failed(self, event: monitoring.CommandFailedEvent): _LOG.exception(hook_exception) span.end() - def _pop_span(self, event): + def _pop_span(self, event: CommandEvent) -> Span | None: return self._span_dict.pop(_get_span_dict_key(event), None) - def _get_statement_by_command_name(self, command_name, event): + def _get_statement_by_command_name( + self, command_name: str, event: CommandEvent + ) -> str: statement = command_name command_attribute = COMMAND_TO_ATTRIBUTE_MAPPING.get(command_name) command = event.command.get(command_attribute) @@ -207,14 +218,16 @@ def _get_statement_by_command_name(self, command_name, event): return statement -def _get_span_dict_key(event): +def _get_span_dict_key( + event: CommandEvent, +) -> int | tuple[int, tuple[str, int | None]]: if event.connection_id is not None: return event.request_id, event.connection_id return event.request_id class PymongoInstrumentor(BaseInstrumentor): - _commandtracer_instance = None # type CommandTracer + _commandtracer_instance: CommandTracer | None = None # The instrumentation for PyMongo is based on the event listener interface # https://api.mongodb.com/python/current/api/pymongo/monitoring.html. # This interface only allows to register listeners and does not provide @@ -225,7 +238,7 @@ class PymongoInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Integrate with pymongo to trace it using event listener. https://api.mongodb.com/python/current/api/pymongo/monitoring.html @@ -259,6 +272,6 @@ def _instrument(self, **kwargs): # If already created, just enable it self._commandtracer_instance.is_enabled = True - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): if self._commandtracer_instance is not None: self._commandtracer_instance.is_enabled = False diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/py.typed b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 29ef6a945550c09a83003577f4d8037b22322038 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Fri, 10 Jan 2025 19:03:09 +0100 Subject: [PATCH 319/335] Add type hints to dbapi (#3068) --- CHANGELOG.md | 2 + docs/nitpick-exceptions.ini | 3 + .../instrumentation/dbapi/__init__.py | 245 ++++++++++-------- .../instrumentation/dbapi/py.typed | 0 4 files changed, 136 insertions(+), 114 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index a6d7340c8c..438f9c787e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints ([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105)) +- `opentelemetry-instrumentation-dbapi` Move `TracedCursorProxy` and `TracedConnectionProxy` to the module level + ([#3068](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3068)) - `opentelemetry-instrumentation-click` Disable tracing of well-known server click commands ([#3174](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3174)) - `opentelemetry-instrumentation` Fix `get_dist_dependency_conflicts` if no distribution requires diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index e27bee26bb..b1fcdd5342 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -41,6 +41,7 @@ py-class= callable Consumer confluent_kafka.Message + ObjectProxy any= ; API @@ -68,6 +69,8 @@ any= py-obj= opentelemetry.propagators.textmap.CarrierT + opentelemetry.instrumentation.dbapi.ConnectionT + opentelemetry.instrumentation.dbapi.CursorT py-func= poll diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index 9b709c584c..27aafc7308 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -37,12 +37,15 @@ --- """ +from __future__ import annotations + import functools import logging import re -import typing +from typing import Any, Callable, Generic, TypeVar import wrapt +from wrapt import wrap_function_wrapper from opentelemetry import trace as trace_api from opentelemetry.instrumentation.dbapi.version import __version__ @@ -61,16 +64,19 @@ _logger = logging.getLogger(__name__) +ConnectionT = TypeVar("ConnectionT") +CursorT = TypeVar("CursorT") + def trace_integration( - connect_module: typing.Callable[..., typing.Any], + connect_module: Callable[..., Any], connect_method_name: str, database_system: str, - connection_attributes: typing.Dict = None, - tracer_provider: typing.Optional[TracerProvider] = None, + connection_attributes: dict[str, Any] | None = None, + tracer_provider: TracerProvider | None = None, capture_parameters: bool = False, enable_commenter: bool = False, - db_api_integration_factory=None, + db_api_integration_factory: type[DatabaseApiIntegration] | None = None, enable_attribute_commenter: bool = False, ): """Integrate with DB API library. @@ -108,16 +114,16 @@ def trace_integration( def wrap_connect( name: str, - connect_module: typing.Callable[..., typing.Any], + connect_module: Callable[..., Any], connect_method_name: str, database_system: str, - connection_attributes: typing.Dict = None, + connection_attributes: dict[str, Any] | None = None, version: str = "", - tracer_provider: typing.Optional[TracerProvider] = None, + tracer_provider: TracerProvider | None = None, capture_parameters: bool = False, enable_commenter: bool = False, - db_api_integration_factory=None, - commenter_options: dict = None, + db_api_integration_factory: type[DatabaseApiIntegration] | None = None, + commenter_options: dict[str, Any] | None = None, enable_attribute_commenter: bool = False, ): """Integrate with DB API library. @@ -146,10 +152,10 @@ def wrap_connect( # pylint: disable=unused-argument def wrap_connect_( - wrapped: typing.Callable[..., typing.Any], - instance: typing.Any, - args: typing.Tuple[typing.Any, typing.Any], - kwargs: typing.Dict[typing.Any, typing.Any], + wrapped: Callable[..., Any], + instance: Any, + args: tuple[Any, Any], + kwargs: dict[Any, Any], ): db_integration = db_api_integration_factory( name, @@ -166,7 +172,7 @@ def wrap_connect_( return db_integration.wrapped_connection(wrapped, args, kwargs) try: - wrapt.wrap_function_wrapper( + wrap_function_wrapper( connect_module, connect_method_name, wrap_connect_ ) except Exception as ex: # pylint: disable=broad-except @@ -174,7 +180,7 @@ def wrap_connect_( def unwrap_connect( - connect_module: typing.Callable[..., typing.Any], connect_method_name: str + connect_module: Callable[..., Any], connect_method_name: str ): """Disable integration with DB API library. https://www.python.org/dev/peps/pep-0249/ @@ -188,17 +194,17 @@ def unwrap_connect( def instrument_connection( name: str, - connection, + connection: ConnectionT | TracedConnectionProxy[ConnectionT], database_system: str, - connection_attributes: typing.Dict = None, + connection_attributes: dict[str, Any] | None = None, version: str = "", - tracer_provider: typing.Optional[TracerProvider] = None, + tracer_provider: TracerProvider | None = None, capture_parameters: bool = False, enable_commenter: bool = False, - commenter_options: dict = None, - connect_module: typing.Callable[..., typing.Any] = None, + commenter_options: dict[str, Any] | None = None, + connect_module: Callable[..., Any] | None = None, enable_attribute_commenter: bool = False, -): +) -> TracedConnectionProxy[ConnectionT]: """Enable instrumentation in a database connection. Args: @@ -238,7 +244,9 @@ def instrument_connection( return get_traced_connection_proxy(connection, db_integration) -def uninstrument_connection(connection): +def uninstrument_connection( + connection: ConnectionT | TracedConnectionProxy[ConnectionT], +) -> ConnectionT: """Disable instrumentation in a database connection. Args: @@ -259,23 +267,24 @@ def __init__( self, name: str, database_system: str, - connection_attributes=None, + connection_attributes: dict[str, Any] | None = None, version: str = "", - tracer_provider: typing.Optional[TracerProvider] = None, + tracer_provider: TracerProvider | None = None, capture_parameters: bool = False, enable_commenter: bool = False, - commenter_options: dict = None, - connect_module: typing.Callable[..., typing.Any] = None, + commenter_options: dict[str, Any] | None = None, + connect_module: Callable[..., Any] | None = None, enable_attribute_commenter: bool = False, ): - self.connection_attributes = connection_attributes - if self.connection_attributes is None: + if connection_attributes is None: self.connection_attributes = { "database": "database", "port": "port", "host": "host", "user": "user", } + else: + self.connection_attributes = connection_attributes self._name = name self._version = version self._tracer = get_tracer( @@ -289,17 +298,14 @@ def __init__( self.commenter_options = commenter_options self.enable_attribute_commenter = enable_attribute_commenter self.database_system = database_system - self.connection_props = {} - self.span_attributes = {} + self.connection_props: dict[str, Any] = {} + self.span_attributes: dict[str, Any] = {} self.name = "" self.database = "" self.connect_module = connect_module self.commenter_data = self.calculate_commenter_data() - def _get_db_version( - self, - db_driver, - ): + def _get_db_version(self, db_driver: str) -> str: if db_driver in _DB_DRIVER_ALIASES: return util_version(_DB_DRIVER_ALIASES[db_driver]) db_version = "" @@ -309,10 +315,8 @@ def _get_db_version( db_version = "unknown" return db_version - def calculate_commenter_data( - self, - ): - commenter_data = {} + def calculate_commenter_data(self) -> dict[str, Any]: + commenter_data: dict[str, Any] = {} if not self.enable_commenter: return commenter_data @@ -339,11 +343,7 @@ def calculate_commenter_data( libpq_version = self.connect_module.__libpq_version__ else: libpq_version = self.connect_module.pq.__build_version__ - commenter_data.update( - { - "libpq_version": libpq_version, - } - ) + commenter_data.update({"libpq_version": libpq_version}) elif self.database_system == "mysql": mysqlc_version = "" if db_driver == "MySQLdb": @@ -351,26 +351,22 @@ def calculate_commenter_data( elif db_driver == "pymysql": mysqlc_version = self.connect_module.get_client_info() - commenter_data.update( - { - "mysql_client_version": mysqlc_version, - } - ) + commenter_data.update({"mysql_client_version": mysqlc_version}) return commenter_data def wrapped_connection( self, - connect_method: typing.Callable[..., typing.Any], - args: typing.Tuple[typing.Any, typing.Any], - kwargs: typing.Dict[typing.Any, typing.Any], - ): + connect_method: Callable[..., ConnectionT], + args: tuple[Any, ...], + kwargs: dict[Any, Any], + ) -> TracedConnectionProxy[ConnectionT]: """Add object proxy to connection object.""" connection = connect_method(*args, **kwargs) self.get_connection_attributes(connection) return get_traced_connection_proxy(connection, self) - def get_connection_attributes(self, connection): + def get_connection_attributes(self, connection: object) -> None: # Populate span fields using connection for key, value in self.connection_attributes.items(): # Allow attributes nested in connection object @@ -404,39 +400,49 @@ def get_connection_attributes(self, connection): self.span_attributes[SpanAttributes.NET_PEER_PORT] = port -def get_traced_connection_proxy( - connection, db_api_integration, *args, **kwargs -): - # pylint: disable=abstract-method - class TracedConnectionProxy(wrapt.ObjectProxy): - # pylint: disable=unused-argument - def __init__(self, connection, *args, **kwargs): - wrapt.ObjectProxy.__init__(self, connection) - - def __getattribute__(self, name): - if object.__getattribute__(self, name): - return object.__getattribute__(self, name) - - return object.__getattribute__( - object.__getattribute__(self, "_connection"), name - ) +# pylint: disable=abstract-method +class TracedConnectionProxy(wrapt.ObjectProxy, Generic[ConnectionT]): + # pylint: disable=unused-argument + def __init__( + self, + connection: ConnectionT, + db_api_integration: DatabaseApiIntegration | None = None, + ): + wrapt.ObjectProxy.__init__(self, connection) + self._self_db_api_integration = db_api_integration - def cursor(self, *args, **kwargs): - return get_traced_cursor_proxy( - self.__wrapped__.cursor(*args, **kwargs), db_api_integration - ) + def __getattribute__(self, name: str): + if object.__getattribute__(self, name): + return object.__getattribute__(self, name) - def __enter__(self): - self.__wrapped__.__enter__() - return self + return object.__getattribute__( + object.__getattribute__(self, "_connection"), name + ) - def __exit__(self, *args, **kwargs): - self.__wrapped__.__exit__(*args, **kwargs) + def cursor(self, *args: Any, **kwargs: Any): + return get_traced_cursor_proxy( + self.__wrapped__.cursor(*args, **kwargs), + self._self_db_api_integration, + ) - return TracedConnectionProxy(connection, *args, **kwargs) + def __enter__(self): + self.__wrapped__.__enter__() + return self + def __exit__(self, *args: Any, **kwargs: Any): + self.__wrapped__.__exit__(*args, **kwargs) -class CursorTracer: + +def get_traced_connection_proxy( + connection: ConnectionT, + db_api_integration: DatabaseApiIntegration | None, + *args: Any, + **kwargs: Any, +) -> TracedConnectionProxy[ConnectionT]: + return TracedConnectionProxy(connection, db_api_integration) + + +class CursorTracer(Generic[CursorT]): def __init__(self, db_api_integration: DatabaseApiIntegration) -> None: self._db_api_integration = db_api_integration self._commenter_enabled = self._db_api_integration.enable_commenter @@ -494,8 +500,8 @@ def _update_args_with_added_sql_comment(self, args, cursor) -> tuple: def _populate_span( self, span: trace_api.Span, - cursor, - *args: typing.Tuple[typing.Any, typing.Any], + cursor: CursorT, + *args: tuple[Any, ...], ): if not span.is_recording(): return @@ -517,13 +523,15 @@ def _populate_span( if self._db_api_integration.capture_parameters and len(args) > 1: span.set_attribute("db.statement.parameters", str(args[1])) - def get_operation_name(self, cursor, args): # pylint: disable=no-self-use + def get_operation_name( + self, cursor: CursorT, args: tuple[Any, ...] + ) -> str: # pylint: disable=no-self-use if args and isinstance(args[0], str): # Strip leading comments so we get the operation name. return self._leading_comment_remover.sub("", args[0]).split()[0] return "" - def get_statement(self, cursor, args): # pylint: disable=no-self-use + def get_statement(self, cursor: CursorT, args: tuple[Any, ...]): # pylint: disable=no-self-use if not args: return "" statement = args[0] @@ -533,10 +541,10 @@ def get_statement(self, cursor, args): # pylint: disable=no-self-use def traced_execution( self, - cursor, - query_method: typing.Callable[..., typing.Any], - *args: typing.Tuple[typing.Any, typing.Any], - **kwargs: typing.Dict[typing.Any, typing.Any], + cursor: CursorT, + query_method: Callable[..., Any], + *args: tuple[Any, ...], + **kwargs: dict[Any, Any], ): name = self.get_operation_name(cursor, args) if not name: @@ -570,35 +578,44 @@ def traced_execution( return query_method(*args, **kwargs) -def get_traced_cursor_proxy(cursor, db_api_integration, *args, **kwargs): - _cursor_tracer = CursorTracer(db_api_integration) +# pylint: disable=abstract-method +class TracedCursorProxy(wrapt.ObjectProxy, Generic[CursorT]): + # pylint: disable=unused-argument + def __init__( + self, + cursor: CursorT, + db_api_integration: DatabaseApiIntegration, + ): + wrapt.ObjectProxy.__init__(self, cursor) + self._self_cursor_tracer = CursorTracer[CursorT](db_api_integration) - # pylint: disable=abstract-method - class TracedCursorProxy(wrapt.ObjectProxy): - # pylint: disable=unused-argument - def __init__(self, cursor, *args, **kwargs): - wrapt.ObjectProxy.__init__(self, cursor) + def execute(self, *args: Any, **kwargs: Any): + return self._self_cursor_tracer.traced_execution( + self.__wrapped__, self.__wrapped__.execute, *args, **kwargs + ) - def execute(self, *args, **kwargs): - return _cursor_tracer.traced_execution( - self.__wrapped__, self.__wrapped__.execute, *args, **kwargs - ) + def executemany(self, *args: Any, **kwargs: Any): + return self._self_cursor_tracer.traced_execution( + self.__wrapped__, self.__wrapped__.executemany, *args, **kwargs + ) - def executemany(self, *args, **kwargs): - return _cursor_tracer.traced_execution( - self.__wrapped__, self.__wrapped__.executemany, *args, **kwargs - ) + def callproc(self, *args: Any, **kwargs: Any): + return self._self_cursor_tracer.traced_execution( + self.__wrapped__, self.__wrapped__.callproc, *args, **kwargs + ) - def callproc(self, *args, **kwargs): - return _cursor_tracer.traced_execution( - self.__wrapped__, self.__wrapped__.callproc, *args, **kwargs - ) + def __enter__(self): + self.__wrapped__.__enter__() + return self - def __enter__(self): - self.__wrapped__.__enter__() - return self + def __exit__(self, *args, **kwargs): + self.__wrapped__.__exit__(*args, **kwargs) - def __exit__(self, *args, **kwargs): - self.__wrapped__.__exit__(*args, **kwargs) - return TracedCursorProxy(cursor, *args, **kwargs) +def get_traced_cursor_proxy( + cursor: CursorT, + db_api_integration: DatabaseApiIntegration, + *args: Any, + **kwargs: Any, +) -> TracedCursorProxy[CursorT]: + return TracedCursorProxy(cursor, db_api_integration) diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/py.typed b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 8406e2e7894bd3832b33fd78124e4bc0b871f790 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Mon, 13 Jan 2025 01:40:43 -0800 Subject: [PATCH 320/335] DB drivers: db.statement inclusion of sqlcomment as opt-in (#3121) * db-api opt-in for enable_attribute_commenter * Refactor db-api traced_execution * Changelog * Update comment * psycopg(2), mysqlclient, pymysql support enable_attribute_commenter * Changelog --- CHANGELOG.md | 8 ++ .../instrumentation/mysqlclient/__init__.py | 26 ++++ .../tests/test_mysqlclient_integration.py | 116 ++++++++++++++++++ .../instrumentation/psycopg/__init__.py | 26 ++++ .../instrumentation/psycopg2/__init__.py | 24 ++++ .../instrumentation/pymysql/__init__.py | 26 ++++ .../tests/test_pymysql_integration.py | 112 +++++++++++++++++ 7 files changed, 338 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 438f9c787e..2c4e76aaf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3115](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3115)) +### Breaking changes + +- `opentelemetry-instrumentation-dbapi` including sqlcomment in `db.statement` span attribute value is now opt-in + ([#3115](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3115)) +- `opentelemetry-instrumentation-psycopg2`, `opentelemetry-instrumentation-psycopg`, `opentelemetry-instrumentation-mysqlclient`, `opentelemetry-instrumentation-pymysql`: including sqlcomment in `db.statement` span attribute value is now opt-in + ([#3121](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3121)) + + ## Version 1.29.0/0.50b0 (2024-12-11) ### Added diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py index e1c07096fa..10c2b23a40 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py @@ -126,6 +126,26 @@ :: Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ +SQLComment in span attribute +**************************** +If sqlcommenter is enabled, you can optionally configure MySQLClient instrumentation to append sqlcomment to query span attribute for convenience of your platform. + +.. code:: python + + from opentelemetry.instrumentation.mysqlclient import MySQLClientInstrumentor + + MySQLClientInstrumentor().instrument( + enable_commenter=True, + enable_attribute_commenter=True, + ) + + +For example, +:: + + Invoking cursor.execute("select * from auth_users") will lead to sql query "select * from auth_users" but when SQLCommenter and attribute_commenter are enabled + the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;" for both server query and `db.statement` span attribute. + API --- """ @@ -159,6 +179,9 @@ def _instrument(self, **kwargs): # pylint: disable=no-self-use tracer_provider = kwargs.get("tracer_provider") enable_sqlcommenter = kwargs.get("enable_commenter", False) commenter_options = kwargs.get("commenter_options", {}) + enable_attribute_commenter = kwargs.get( + "enable_attribute_commenter", False + ) dbapi.wrap_connect( __name__, @@ -170,6 +193,7 @@ def _instrument(self, **kwargs): # pylint: disable=no-self-use tracer_provider=tracer_provider, enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, + enable_attribute_commenter=enable_attribute_commenter, ) def _uninstrument(self, **kwargs): # pylint: disable=no-self-use @@ -182,6 +206,7 @@ def instrument_connection( tracer_provider=None, enable_commenter=None, commenter_options=None, + enable_attribute_commenter=None, ): """Enable instrumentation in a mysqlclient connection. @@ -220,6 +245,7 @@ def instrument_connection( enable_commenter=enable_commenter, commenter_options=commenter_options, connect_module=MySQLdb, + enable_attribute_commenter=enable_attribute_commenter, ) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py index ae221f68f4..e2b1e41aa3 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py @@ -19,6 +19,7 @@ import opentelemetry.instrumentation.mysqlclient from opentelemetry.instrumentation.mysqlclient import MySQLClientInstrumentor from opentelemetry.sdk import resources +from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase @@ -110,12 +111,14 @@ def test_instrument_connection_enable_commenter_dbapi_kwargs( cnx, enable_commenter=True, commenter_options={"foo": True}, + enable_attribute_commenter=True, ) cursor = cnx.cursor() cursor.execute("Select 1;") kwargs = mock_instrument_connection.call_args[1] self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": True}) + self.assertEqual(kwargs["enable_attribute_commenter"], True) def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): mock_connect_module = mock.MagicMock( @@ -150,6 +153,51 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_instrument_connection_with_dbapi_sqlcomment_enabled_stmt_enabled( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + cnx_proxy = MySQLClientInstrumentor().instrument_connection( + mock_connection, + enable_commenter=True, + enable_attribute_commenter=True, + ) + cnx_proxy.cursor().execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options( self, @@ -191,6 +239,10 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options( mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( self, @@ -221,6 +273,12 @@ def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( mock_cursor.execute.call_args[0][0], "Select 1;", ) + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") @mock.patch("MySQLdb.connect") @@ -233,10 +291,12 @@ def test_instrument_enable_commenter_dbapi_kwargs( MySQLClientInstrumentor()._instrument( enable_commenter=True, commenter_options={"foo": True}, + enable_attribute_commenter=True, ) kwargs = mock_wrap_connect.call_args[1] self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": True}) + self.assertEqual(kwargs["enable_attribute_commenter"], True) def test_instrument_with_dbapi_sqlcomment_enabled( self, @@ -274,6 +334,52 @@ def test_instrument_with_dbapi_sqlcomment_enabled( mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_instrument_with_dbapi_sqlcomment_enabled_stmt_enabled( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="MySQLdb", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module._mysql.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.mysqlclient.MySQLdb", + mock_connect_module, + ), mock.patch( + "opentelemetry.instrumentation.dbapi.util_version", + return_value="foobar", + ): + MySQLClientInstrumentor()._instrument( + enable_commenter=True, + enable_attribute_commenter=True, + ) + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) def test_instrument_with_dbapi_sqlcomment_enabled_with_options( self, @@ -316,6 +422,10 @@ def test_instrument_with_dbapi_sqlcomment_enabled_with_options( mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='MySQLdb%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) def test_instrument_with_dbapi_sqlcomment_not_enabled_default( self, @@ -346,6 +456,12 @@ def test_instrument_with_dbapi_sqlcomment_not_enabled_default( mock_cursor.execute.call_args[0][0], "Select 1;", ) + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) @mock.patch("MySQLdb.connect") # pylint: disable=unused-argument diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py index 8c608b7655..81390ed48f 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py @@ -80,6 +80,26 @@ :: Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ +SQLComment in span attribute +**************************** +If sqlcommenter is enabled, you can optionally configure psycopg instrumentation to append sqlcomment to query span attribute for convenience of your platform. + +.. code:: python + + from opentelemetry.instrumentation.psycopg import PsycopgInstrumentor + + PsycopgInstrumentor().instrument( + enable_commenter=True, + enable_attribute_commenter=True, + ) + + +For example, +:: + + Invoking cursor.execute("select * from auth_users") will lead to postgresql query "select * from auth_users" but when SQLCommenter and attribute_commenter are enabled + the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;" for both server query and `db.statement` span attribute. + Usage ----- @@ -159,6 +179,9 @@ def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider") enable_sqlcommenter = kwargs.get("enable_commenter", False) commenter_options = kwargs.get("commenter_options", {}) + enable_attribute_commenter = kwargs.get( + "enable_attribute_commenter", False + ) dbapi.wrap_connect( __name__, psycopg, @@ -170,6 +193,7 @@ def _instrument(self, **kwargs): db_api_integration_factory=DatabaseApiIntegration, enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, + enable_attribute_commenter=enable_attribute_commenter, ) dbapi.wrap_connect( @@ -183,6 +207,7 @@ def _instrument(self, **kwargs): db_api_integration_factory=DatabaseApiIntegration, enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, + enable_attribute_commenter=enable_attribute_commenter, ) dbapi.wrap_connect( __name__, @@ -195,6 +220,7 @@ def _instrument(self, **kwargs): db_api_integration_factory=DatabaseApiAsyncIntegration, enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, + enable_attribute_commenter=enable_attribute_commenter, ) def _uninstrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py index a811f4285a..f03ad1de0d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py @@ -80,6 +80,26 @@ :: Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ +SQLComment in span attribute +**************************** +If sqlcommenter is enabled, you can optionally configure psycopg2 instrumentation to append sqlcomment to query span attribute for convenience of your platform. + +.. code:: python + + from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor + + Psycopg2Instrumentor().instrument( + enable_commenter=True, + enable_attribute_commenter=True, + ) + + +For example, +:: + + Invoking cursor.execute("select * from auth_users") will lead to postgresql query "select * from auth_users" but when SQLCommenter and attribute_commenter are enabled + the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;" for both server query and `db.statement` span attribute. + Usage ----- @@ -156,6 +176,9 @@ def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider") enable_sqlcommenter = kwargs.get("enable_commenter", False) commenter_options = kwargs.get("commenter_options", {}) + enable_attribute_commenter = kwargs.get( + "enable_attribute_commenter", False + ) dbapi.wrap_connect( __name__, psycopg2, @@ -167,6 +190,7 @@ def _instrument(self, **kwargs): db_api_integration_factory=DatabaseApiIntegration, enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, + enable_attribute_commenter=enable_attribute_commenter, ) def _uninstrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py index 54c614f745..24e5c34062 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/__init__.py @@ -128,6 +128,26 @@ :: Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ +SQLComment in span attribute +**************************** +If sqlcommenter is enabled, you can optionally configure PyMySQL instrumentation to append sqlcomment to query span attribute for convenience of your platform. + +.. code:: python + + from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor + + PyMySQLInstrumentor().instrument( + enable_commenter=True, + enable_attribute_commenter=True, + ) + + +For example, +:: + + Invoking cursor.execute("select * from auth_users") will lead to sql query "select * from auth_users" but when SQLCommenter and attribute_commenter are enabled + the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;" for both server query and `db.statement` span attribute. + API --- """ @@ -161,6 +181,9 @@ def _instrument(self, **kwargs): # pylint: disable=no-self-use tracer_provider = kwargs.get("tracer_provider") enable_sqlcommenter = kwargs.get("enable_commenter", False) commenter_options = kwargs.get("commenter_options", {}) + enable_attribute_commenter = kwargs.get( + "enable_attribute_commenter", False + ) dbapi.wrap_connect( __name__, @@ -172,6 +195,7 @@ def _instrument(self, **kwargs): # pylint: disable=no-self-use tracer_provider=tracer_provider, enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, + enable_attribute_commenter=enable_attribute_commenter, ) def _uninstrument(self, **kwargs): # pylint: disable=no-self-use @@ -184,6 +208,7 @@ def instrument_connection( tracer_provider=None, enable_commenter=None, commenter_options=None, + enable_attribute_commenter=None, ): """Enable instrumentation in a PyMySQL connection. @@ -216,6 +241,7 @@ def instrument_connection( enable_commenter=enable_commenter, commenter_options=commenter_options, connect_module=pymysql, + enable_attribute_commenter=enable_attribute_commenter, ) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py index 82294236f0..ea59e5df7b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/tests/test_pymysql_integration.py @@ -20,6 +20,7 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor from opentelemetry.sdk import resources +from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase @@ -125,12 +126,14 @@ def test_instrument_connection_enable_commenter_dbapi_kwargs( cnx, enable_commenter=True, commenter_options={"foo": True}, + enable_attribute_commenter=True, ) cursor = cnx.cursor() cursor.execute("SELECT * FROM test") kwargs = mock_instrument_connection.call_args[1] self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": True}) + self.assertEqual(kwargs["enable_attribute_commenter"], True) def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): mock_connect_module = mock.MagicMock( @@ -163,6 +166,49 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_instrument_connection_with_dbapi_sqlcomment_enabled_stmt_enabled( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + cnx_proxy = PyMySQLInstrumentor().instrument_connection( + mock_connection, + enable_commenter=True, + enable_attribute_commenter=True, + ) + cnx_proxy.cursor().execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options( self, @@ -202,6 +248,10 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options( mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( self, @@ -230,6 +280,12 @@ def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( mock_cursor.execute.call_args[0][0], "Select 1;", ) + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") @mock.patch("pymysql.connect") @@ -242,10 +298,12 @@ def test_instrument_enable_commenter_dbapi_kwargs( PyMySQLInstrumentor()._instrument( enable_commenter=True, commenter_options={"foo": True}, + enable_attribute_commenter=True, ) kwargs = mock_wrap_connect.call_args[1] self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": True}) + self.assertEqual(kwargs["enable_attribute_commenter"], True) def test_instrument_with_dbapi_sqlcomment_enabled( self, @@ -281,6 +339,50 @@ def test_instrument_with_dbapi_sqlcomment_enabled( mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) + + def test_instrument_with_dbapi_sqlcomment_enabled_stmt_enabled( + self, + ): + mock_connect_module = mock.MagicMock( + __name__="pymysql", + __version__="foobar", + threadsafety="123", + apilevel="123", + paramstyle="test", + ) + mock_connect_module.get_client_info.return_value = "foobaz" + mock_cursor = mock_connect_module.connect().cursor() + mock_connection = mock.MagicMock() + mock_connection.cursor.return_value = mock_cursor + + with mock.patch( + "opentelemetry.instrumentation.pymysql.pymysql", + mock_connect_module, + ): + PyMySQLInstrumentor()._instrument( + enable_commenter=True, + enable_attribute_commenter=True, + ) + cnx = mock_connect_module.connect(database="test") + cursor = cnx.cursor() + cursor.execute("Select 1;") + + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + span_id = format(span.get_span_context().span_id, "016x") + trace_id = format(span.get_span_context().trace_id, "032x") + self.assertEqual( + mock_cursor.execute.call_args[0][0], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_level='123',dbapi_threadsafety='123',driver_paramstyle='test',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", + ) def test_instrument_with_dbapi_sqlcomment_enabled_with_options( self, @@ -321,6 +423,10 @@ def test_instrument_with_dbapi_sqlcomment_enabled_with_options( mock_cursor.execute.call_args[0][0], f"Select 1 /*db_driver='pymysql%%3Afoobar',dbapi_threadsafety='123',mysql_client_version='foobaz',traceparent='00-{trace_id}-{span_id}-01'*/;", ) + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) def test_instrument_with_dbapi_sqlcomment_not_enabled_default( self, @@ -349,6 +455,12 @@ def test_instrument_with_dbapi_sqlcomment_not_enabled_default( mock_cursor.execute.call_args[0][0], "Select 1;", ) + spans_list = self.memory_exporter.get_finished_spans() + span = spans_list[0] + self.assertEqual( + span.attributes[SpanAttributes.DB_STATEMENT], + "Select 1;", + ) @mock.patch("pymysql.connect") # pylint: disable=unused-argument From 406707b2bd322b6fe5819a6123b0deee1c6f21d1 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Mon, 13 Jan 2025 17:20:33 +0000 Subject: [PATCH 321/335] Add type checker (#3116) --- .github/workflows/misc_0.yml | 18 ++++++++ dev-requirements.txt | 2 +- .../instrumentation/threading/__init__.py | 45 +++++++++++++++---- pyproject.toml | 16 +++++++ tox.ini | 12 ++++- 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 1148f85abd..422669b86f 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -152,3 +152,21 @@ jobs: - name: Run tests run: tox -e ruff + + typecheck: + name: typecheck + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e typecheck diff --git a/dev-requirements.txt b/dev-requirements.txt index 2668677cc5..46ba31346e 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,6 @@ pylint==3.0.2 httpretty==1.1.4 -mypy==0.931 +pyright==v1.1.390 sphinx==7.1.2 sphinx-rtd-theme==2.0.0rc4 sphinx-autodoc-typehints==1.25.2 diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/__init__.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/__init__.py index be1eec139e..9488e3ce47 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/__init__.py @@ -35,17 +35,29 @@ run method or the executor's worker thread." """ +from __future__ import annotations + import threading from concurrent import futures -from typing import Collection +from typing import TYPE_CHECKING, Any, Callable, Collection -from wrapt import wrap_function_wrapper +from wrapt import ( + wrap_function_wrapper, # type: ignore[reportUnknownVariableType] +) from opentelemetry import context from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.threading.package import _instruments from opentelemetry.instrumentation.utils import unwrap +if TYPE_CHECKING: + from typing import Protocol, TypeVar + + R = TypeVar("R") + + class HasOtelContext(Protocol): + _otel_context: context.Context + class ThreadingInstrumentor(BaseInstrumentor): __WRAPPER_START_METHOD = "start" @@ -55,12 +67,12 @@ class ThreadingInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): self._instrument_thread() self._instrument_timer() self._instrument_thread_pool() - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): self._uninstrument_thread() self._uninstrument_timer() self._uninstrument_thread_pool() @@ -117,12 +129,22 @@ def _uninstrument_thread_pool(): ) @staticmethod - def __wrap_threading_start(call_wrapped, instance, args, kwargs): + def __wrap_threading_start( + call_wrapped: Callable[[], None], + instance: HasOtelContext, + args: ..., + kwargs: ..., + ) -> None: instance._otel_context = context.get_current() return call_wrapped(*args, **kwargs) @staticmethod - def __wrap_threading_run(call_wrapped, instance, args, kwargs): + def __wrap_threading_run( + call_wrapped: Callable[..., R], + instance: HasOtelContext, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> R: token = None try: token = context.attach(instance._otel_context) @@ -131,12 +153,17 @@ def __wrap_threading_run(call_wrapped, instance, args, kwargs): context.detach(token) @staticmethod - def __wrap_thread_pool_submit(call_wrapped, instance, args, kwargs): + def __wrap_thread_pool_submit( + call_wrapped: Callable[..., R], + instance: futures.ThreadPoolExecutor, + args: tuple[Callable[..., Any], ...], + kwargs: dict[str, Any], + ) -> R: # obtain the original function and wrapped kwargs original_func = args[0] otel_context = context.get_current() - def wrapped_func(*func_args, **func_kwargs): + def wrapped_func(*func_args: Any, **func_kwargs: Any) -> R: token = None try: token = context.attach(otel_context) @@ -145,5 +172,5 @@ def wrapped_func(*func_args, **func_kwargs): context.detach(token) # replace the original function with the wrapped function - new_args = (wrapped_func,) + args[1:] + new_args: tuple[Callable[..., Any], ...] = (wrapped_func,) + args[1:] return call_wrapped(*new_args, **kwargs) diff --git a/pyproject.toml b/pyproject.toml index fd5ee5716f..6ba2e933c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,3 +39,19 @@ known-third-party = [ "opencensus", ] +# https://github.com/microsoft/pyright/blob/main/docs/configuration.md#type-check-rule-overrides +[tool.pyright] +typeCheckingMode = "strict" +reportUnnecessaryTypeIgnoreComment = true +reportMissingTypeStubs = false +pythonVersion = "3.8" +reportPrivateUsage = false # Ignore private attributes added by instrumentation packages. +# Add progressively instrumentation packages here. +include = [ + "instrumentation/opentelemetry-instrumentation-threading/**/*.py" +] +# We should also add type hints to the test suite - It helps on finding bugs. +# We are excluding for now because it's easier, and more important to add to the instrumentation packages. +exclude = [ + "instrumentation/opentelemetry-instrumentation-threading/tests/**", +] diff --git a/tox.ini b/tox.ini index 2f1c0a577e..feeda77702 100644 --- a/tox.ini +++ b/tox.ini @@ -404,6 +404,7 @@ envlist = generate-workflows shellcheck ruff + typecheck [testenv] test_deps = @@ -677,7 +678,6 @@ deps = util-http: -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt util-http: {toxinidir}/util/opentelemetry-util-http ; FIXME: add coverage testing - ; FIXME: add mypy testing allowlist_externals = sh @@ -986,3 +986,13 @@ deps = pre-commit commands = pre-commit run --color=always --all-files {posargs} + +[testenv:typecheck] +deps = + -c {toxinidir}/dev-requirements.txt + pyright + {[testenv]test_deps} + {toxinidir}/opentelemetry-instrumentation + {toxinidir}/util/opentelemetry-util-http +commands = + pyright From b7e7d0cbe58e5e525c330b4d3a38e831da588f8e Mon Sep 17 00:00:00 2001 From: Filip Nikolovski Date: Mon, 13 Jan 2025 20:49:22 +0100 Subject: [PATCH 322/335] Implement new HTTP semantic convention opt-in for Falcon (#2790) --- CHANGELOG.md | 2 + instrumentation/README.md | 2 +- .../instrumentation/falcon/__init__.py | 150 +++++--- .../instrumentation/falcon/package.py | 2 + .../tests/test_falcon.py | 350 +++++++++++++++--- 5 files changed, 406 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c4e76aaf8..0848cf9f7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3133](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3133)) - `opentelemetry-instrumentation-falcon` add support version to v4 ([#3086](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3086)) +- `opentelemetry-instrumentation-falcon` Implement new HTTP semantic convention opt-in for Falcon + ([#2790](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2790)) - `opentelemetry-instrumentation-wsgi` always record span status code to have it available in metrics ([#3148](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3148)) - add support to Python 3.13 diff --git a/instrumentation/README.md b/instrumentation/README.md index d1b383d5a6..75341dad9a 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -20,7 +20,7 @@ | [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | experimental | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | experimental | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | experimental -| [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 5.0.0 | Yes | experimental +| [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 5.0.0 | Yes | migration | [opentelemetry-instrumentation-fastapi](./opentelemetry-instrumentation-fastapi) | fastapi ~= 0.58 | Yes | migration | [opentelemetry-instrumentation-flask](./opentelemetry-instrumentation-flask) | flask >= 1.0 | Yes | migration | [opentelemetry-instrumentation-grpc](./opentelemetry-instrumentation-grpc) | grpcio >= 1.42.0 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 1037f98f5f..2b26c55cb1 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -193,6 +193,14 @@ def response_hook(span, req, resp): import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace +from opentelemetry.instrumentation._semconv import ( + _get_schema_url, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _report_old, + _StabilityMode, +) from opentelemetry.instrumentation.falcon.package import _instruments from opentelemetry.instrumentation.falcon.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -203,18 +211,22 @@ def response_hook(span, req, resp): from opentelemetry.instrumentation.utils import ( _start_internal_or_server_span, extract_attributes_from_object, - http_status_to_status_code, ) from opentelemetry.metrics import get_meter +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_ROUTE, +) from opentelemetry.semconv.metrics import MetricInstruments -from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs _logger = getLogger(__name__) _ENVIRON_STARTTIME_KEY = "opentelemetry-falcon.starttime_key" _ENVIRON_SPAN_KEY = "opentelemetry-falcon.span_key" +_ENVIRON_REQ_ATTRS = "opentelemetry-falcon.req_attrs" _ENVIRON_ACTIVATION_KEY = "opentelemetry-falcon.activation_key" _ENVIRON_TOKEN = "opentelemetry-falcon.token" _ENVIRON_EXC = "opentelemetry-falcon.exc" @@ -243,6 +255,10 @@ class _InstrumentedFalconAPI(getattr(falcon, _instrument_app)): def __init__(self, *args, **kwargs): otel_opts = kwargs.pop("_otel_opts", {}) + self._sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + # inject trace middleware self._middlewares_list = kwargs.pop("middleware", []) if self._middlewares_list is None: @@ -257,19 +273,30 @@ def __init__(self, *args, **kwargs): __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=_get_schema_url(self._sem_conv_opt_in_mode), ) self._otel_meter = get_meter( __name__, __version__, meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", - ) - self.duration_histogram = self._otel_meter.create_histogram( - name=MetricInstruments.HTTP_SERVER_DURATION, - unit="ms", - description="Measures the duration of inbound HTTP requests.", + schema_url=_get_schema_url(self._sem_conv_opt_in_mode), ) + + self.duration_histogram_old = None + if _report_old(self._sem_conv_opt_in_mode): + self.duration_histogram_old = self._otel_meter.create_histogram( + name=MetricInstruments.HTTP_SERVER_DURATION, + unit="ms", + description="Measures the duration of inbound HTTP requests.", + ) + self.duration_histogram_new = None + if _report_new(self._sem_conv_opt_in_mode): + self.duration_histogram_new = self._otel_meter.create_histogram( + name=HTTP_SERVER_REQUEST_DURATION, + description="Duration of HTTP server requests.", + unit="s", + ) + self.active_requests_counter = self._otel_meter.create_up_down_counter( name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS, unit="requests", @@ -283,6 +310,7 @@ def __init__(self, *args, **kwargs): ), otel_opts.pop("request_hook", None), otel_opts.pop("response_hook", None), + self._sem_conv_opt_in_mode, ) self._middlewares_list.insert(0, trace_middleware) kwargs["middleware"] = self._middlewares_list @@ -343,11 +371,14 @@ def __call__(self, env, start_response): context_carrier=env, context_getter=otel_wsgi.wsgi_getter, ) - attributes = otel_wsgi.collect_request_attributes(env) + attributes = otel_wsgi.collect_request_attributes( + env, self._sem_conv_opt_in_mode + ) active_requests_count_attrs = ( - otel_wsgi._parse_active_request_count_attrs(attributes) + otel_wsgi._parse_active_request_count_attrs( + attributes, self._sem_conv_opt_in_mode + ) ) - duration_attrs = otel_wsgi._parse_duration_attrs(attributes) self.active_requests_counter.add(1, active_requests_count_attrs) if span.is_recording(): @@ -364,6 +395,7 @@ def __call__(self, env, start_response): activation.__enter__() env[_ENVIRON_SPAN_KEY] = span env[_ENVIRON_ACTIVATION_KEY] = activation + env[_ENVIRON_REQ_ATTRS] = attributes exception = None def _start_response(status, response_headers, *args, **kwargs): @@ -379,12 +411,22 @@ def _start_response(status, response_headers, *args, **kwargs): exception = exc raise finally: - if span.is_recording(): - duration_attrs[SpanAttributes.HTTP_STATUS_CODE] = ( - span.attributes.get(SpanAttributes.HTTP_STATUS_CODE) + duration_s = default_timer() - start + if self.duration_histogram_old: + duration_attrs = otel_wsgi._parse_duration_attrs( + attributes, _StabilityMode.DEFAULT + ) + self.duration_histogram_old.record( + max(round(duration_s * 1000), 0), duration_attrs + ) + if self.duration_histogram_new: + duration_attrs = otel_wsgi._parse_duration_attrs( + attributes, _StabilityMode.HTTP + ) + self.duration_histogram_new.record( + max(duration_s, 0), duration_attrs ) - duration = max(round((default_timer() - start) * 1000), 0) - self.duration_histogram.record(duration, duration_attrs) + self.active_requests_counter.add(-1, active_requests_count_attrs) if exception is None: activation.__exit__(None, None, None) @@ -407,11 +449,13 @@ def __init__( traced_request_attrs=None, request_hook=None, response_hook=None, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): self.tracer = tracer self._traced_request_attrs = traced_request_attrs self._request_hook = request_hook self._response_hook = response_hook + self._sem_conv_opt_in_mode = sem_conv_opt_in_mode def process_request(self, req, resp): span = req.env.get(_ENVIRON_SPAN_KEY) @@ -437,58 +481,60 @@ def process_resource(self, req, resp, resource, params): def process_response(self, req, resp, resource, req_succeeded=None): # pylint:disable=R0201,R0912 span = req.env.get(_ENVIRON_SPAN_KEY) + req_attrs = req.env.get(_ENVIRON_REQ_ATTRS) - if not span or not span.is_recording(): + if not span: return status = resp.status - reason = None if resource is None: - status = "404" - reason = "NotFound" + status = falcon.HTTP_404 else: + exc_type, exc = None, None if _ENVIRON_EXC in req.env: exc = req.env[_ENVIRON_EXC] exc_type = type(exc) - else: - exc_type, exc = None, None + if exc_type and not req_succeeded: if "HTTPNotFound" in exc_type.__name__: - status = "404" - reason = "NotFound" + status = falcon.HTTP_404 + elif isinstance(exc, (falcon.HTTPError, falcon.HTTPStatus)): + try: + if _falcon_version > 2: + status = falcon.code_to_http_status(exc.status) + else: + status = exc.status + except ValueError: + status = falcon.HTTP_500 else: - status = "500" - reason = f"{exc_type.__name__}: {exc}" + status = falcon.HTTP_500 + + # Falcon 1 does not support response headers. So + # send an empty dict. + response_headers = {} + if _falcon_version > 1: + response_headers = resp.headers + + otel_wsgi.add_response_attributes( + span, + status, + response_headers, + req_attrs, + self._sem_conv_opt_in_mode, + ) - status = status.split(" ")[0] + if ( + _report_new(self._sem_conv_opt_in_mode) + and req.uri_template + and req_attrs is not None + ): + req_attrs[HTTP_ROUTE] = req.uri_template try: - status_code = int(status) - span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) - otel_status_code = http_status_to_status_code( - status_code, server_span=True - ) - - # set the description only when the status code is ERROR - if otel_status_code is not StatusCode.ERROR: - reason = None - - span.set_status( - Status( - status_code=otel_status_code, - description=reason, - ) - ) - - # Falcon 1 does not support response headers. So - # send an empty dict. - response_headers = {} - if _falcon_version > 1: - response_headers = resp.headers - if span.is_recording() and span.kind == trace.SpanKind.SERVER: # Check if low-cardinality route is available as per semantic-conventions if req.uri_template: span.update_name(f"{req.method} {req.uri_template}") + span.set_attribute(HTTP_ROUTE, req.uri_template) else: span.update_name(f"{req.method}") diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py index 440a6e25f2..74651ddc42 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/package.py @@ -16,3 +16,5 @@ _instruments = ("falcon >= 1.4.1, < 5.0.0",) _supports_metrics = True + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py index f940deb34e..48cbdbe3f8 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py @@ -22,7 +22,11 @@ from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, + _server_active_requests_count_attrs_new, _server_active_requests_count_attrs_old, + _server_duration_attrs_new, _server_duration_attrs_old, ) from opentelemetry.instrumentation.falcon import FalconInstrumentor @@ -36,6 +40,24 @@ NumberDataPoint, ) from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.attributes.client_attributes import ( + CLIENT_PORT, +) +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import ( + URL_PATH, + URL_SCHEME, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase @@ -52,10 +74,33 @@ "http.server.active_requests", "http.server.duration", ] + _recommended_attrs = { + "http.server.active_requests": _server_active_requests_count_attrs_new + + _server_active_requests_count_attrs_old, + "http.server.duration": _server_duration_attrs_new + + _server_duration_attrs_old, +} + +_recommended_metrics_attrs_old = { "http.server.active_requests": _server_active_requests_count_attrs_old, "http.server.duration": _server_duration_attrs_old, } +_recommended_metrics_attrs_new = { + "http.server.active_requests": _server_active_requests_count_attrs_new, + "http.server.request.duration": _server_duration_attrs_new, +} +_server_active_requests_count_attrs_both = ( + _server_active_requests_count_attrs_old +) +_server_active_requests_count_attrs_both.extend( + _server_active_requests_count_attrs_new +) +_recommended_metrics_attrs_both = { + "http.server.active_requests": _server_active_requests_count_attrs_both, + "http.server.duration": _server_duration_attrs_old, + "http.server.request.duration": _server_duration_attrs_new, +} _parsed_falcon_version = package_version.parse(_falcon_version) @@ -63,13 +108,26 @@ class TestFalconBase(TestBase): def setUp(self): super().setUp() + + test_name = "" + if hasattr(self, "_testMethodName"): + test_name = self._testMethodName + sem_conv_mode = "default" + if "new_semconv" in test_name: + sem_conv_mode = "http" + elif "both_semconv" in test_name: + sem_conv_mode = "http/dup" + self.env_patch = patch.dict( "os.environ", { "OTEL_PYTHON_FALCON_EXCLUDED_URLS": "ping", "OTEL_PYTHON_FALCON_TRACED_REQUEST_ATTRS": "query_string", + OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) + + _OpenTelemetrySemanticConventionStability._initialized = False self.env_patch.start() FalconInstrumentor().instrument( @@ -95,26 +153,63 @@ def tearDown(self): self.env_patch.stop() +# pylint: disable=too-many-public-methods class TestFalconInstrumentation(TestFalconBase, WsgiTestBase): def test_get(self): self._test_method("GET") + def test_get_new_semconv(self): + self._test_method("GET", old_semconv=False, new_semconv=True) + + def test_get_both_semconv(self): + self._test_method("GET", old_semconv=True, new_semconv=True) + def test_post(self): self._test_method("POST") + def test_post_new_semconv(self): + self._test_method("POST", old_semconv=False, new_semconv=True) + + def test_post_both_semconv(self): + self._test_method("POST", old_semconv=True, new_semconv=True) + def test_patch(self): self._test_method("PATCH") + def test_patch_new_semconv(self): + self._test_method("PATCH", old_semconv=False, new_semconv=True) + + def test_patch_both_semconv(self): + self._test_method("PATCH", old_semconv=True, new_semconv=True) + def test_put(self): self._test_method("PUT") + def test_put_new_semconv(self): + self._test_method("PUT", old_semconv=False, new_semconv=True) + + def test_put_both_semconv(self): + self._test_method("PUT", old_semconv=True, new_semconv=True) + def test_delete(self): self._test_method("DELETE") + def test_delete_new_semconv(self): + self._test_method("DELETE", old_semconv=False, new_semconv=True) + + def test_delete_both_semconv(self): + self._test_method("DELETE", old_semconv=True, new_semconv=True) + def test_head(self): self._test_method("HEAD") - def _test_method(self, method): + def test_head_new_semconv(self): + self._test_method("HEAD", old_semconv=False, new_semconv=True) + + def test_head_both_semconv(self): + self._test_method("HEAD", old_semconv=True, new_semconv=True) + + def _test_method(self, method, old_semconv=True, new_semconv=False): self.client().simulate_request(method=method, path="/hello") spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 1) @@ -125,23 +220,42 @@ def _test_method(self, method): span.status.description, None, ) - self.assertSpanHasAttributes( - span, - { - SpanAttributes.HTTP_METHOD: method, - SpanAttributes.HTTP_SERVER_NAME: "falconframework.org", - SpanAttributes.HTTP_SCHEME: "http", - SpanAttributes.NET_HOST_PORT: 80, - SpanAttributes.HTTP_HOST: "falconframework.org", - SpanAttributes.HTTP_TARGET: "/" - if self._has_fixed_http_target - else "/hello", - SpanAttributes.NET_PEER_PORT: 65133, - SpanAttributes.HTTP_FLAVOR: "1.1", - "falcon.resource": "HelloWorldResource", - SpanAttributes.HTTP_STATUS_CODE: 201, - }, - ) + + expected_attributes = {} + expected_attributes_old = { + SpanAttributes.HTTP_METHOD: method, + SpanAttributes.HTTP_SERVER_NAME: "falconframework.org", + SpanAttributes.HTTP_SCHEME: "http", + SpanAttributes.NET_HOST_PORT: 80, + SpanAttributes.HTTP_HOST: "falconframework.org", + SpanAttributes.HTTP_TARGET: "/" + if self._has_fixed_http_target + else "/hello", + SpanAttributes.NET_PEER_PORT: 65133, + SpanAttributes.HTTP_FLAVOR: "1.1", + "falcon.resource": "HelloWorldResource", + SpanAttributes.HTTP_STATUS_CODE: 201, + SpanAttributes.HTTP_ROUTE: "/hello", + } + expected_attributes_new = { + HTTP_REQUEST_METHOD: method, + SERVER_ADDRESS: "falconframework.org", + URL_SCHEME: "http", + SERVER_PORT: 80, + URL_PATH: "/" if self._has_fixed_http_target else "/hello", + CLIENT_PORT: 65133, + NETWORK_PROTOCOL_VERSION: "1.1", + "falcon.resource": "HelloWorldResource", + HTTP_RESPONSE_STATUS_CODE: 201, + SpanAttributes.HTTP_ROUTE: "/hello", + } + + if old_semconv: + expected_attributes.update(expected_attributes_old) + if new_semconv: + expected_attributes.update(expected_attributes_new) + + self.assertSpanHasAttributes(span, expected_attributes) # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1 # In falcon>=3, NET_PEER_IP is not set to anything by default # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa @@ -193,10 +307,16 @@ def test_500(self): self.assertEqual(span.name, "GET /error") self.assertFalse(span.status.is_ok) self.assertEqual(span.status.status_code, StatusCode.ERROR) - self.assertEqual( - span.status.description, - "NameError: name 'non_existent_var' is not defined", - ) + + _parsed_falcon_version = package_version.parse(_falcon_version) + if _parsed_falcon_version < package_version.parse("3.0.0"): + self.assertEqual( + span.status.description, + "NameError: name 'non_existent_var' is not defined", + ) + else: + self.assertEqual(span.status.description, None) + self.assertSpanHasAttributes( span, { @@ -211,6 +331,7 @@ def test_500(self): SpanAttributes.NET_PEER_PORT: 65133, SpanAttributes.HTTP_FLAVOR: "1.1", SpanAttributes.HTTP_STATUS_CODE: 500, + SpanAttributes.HTTP_ROUTE: "/error", }, ) # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1 @@ -221,6 +342,47 @@ def test_500(self): span.attributes[SpanAttributes.NET_PEER_IP], "127.0.0.1" ) + def test_url_template_new_semconv(self): + self.client().simulate_get("/user/123") + spans = self.memory_exporter.get_finished_spans() + metrics_list = self.memory_metrics_reader.get_metrics_data() + + self.assertEqual(len(spans), 1) + self.assertTrue(len(metrics_list.resource_metrics) != 0) + span = spans[0] + self.assertEqual(span.name, "GET /user/{user_id}") + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual( + span.status.description, + None, + ) + self.assertSpanHasAttributes( + span, + { + HTTP_REQUEST_METHOD: "GET", + SERVER_ADDRESS: "falconframework.org", + URL_SCHEME: "http", + SERVER_PORT: 80, + URL_PATH: "/" if self._has_fixed_http_target else "/user/123", + CLIENT_PORT: 65133, + NETWORK_PROTOCOL_VERSION: "1.1", + "falcon.resource": "UserResource", + HTTP_RESPONSE_STATUS_CODE: 200, + SpanAttributes.HTTP_ROUTE: "/user/{user_id}", + }, + ) + + for resource_metric in metrics_list.resource_metrics: + for scope_metric in resource_metric.scope_metrics: + for metric in scope_metric.metrics: + if metric.name == "http.server.request.duration": + data_points = list(metric.data.data_points) + for point in data_points: + self.assertIn( + "http.route", + point.attributes, + ) + def test_url_template(self): self.client().simulate_get("/user/123") spans = self.memory_exporter.get_finished_spans() @@ -247,6 +409,7 @@ def test_url_template(self): SpanAttributes.HTTP_FLAVOR: "1.1", "falcon.resource": "UserResource", SpanAttributes.HTTP_STATUS_CODE: 200, + SpanAttributes.HTTP_ROUTE: "/user/{user_id}", }, ) @@ -305,6 +468,27 @@ def test_traced_not_recording(self): self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) + metrics_list = self.memory_metrics_reader.get_metrics_data() + self.assertTrue(len(metrics_list.resource_metrics) != 0) + + for resource_metric in metrics_list.resource_metrics: + for scope_metric in resource_metric.scope_metrics: + for metric in scope_metric.metrics: + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + if isinstance(point, NumberDataPoint): + self.assertEqual(point.value, 0) + for attr in point.attributes: + self.assertIn( + attr, + _recommended_metrics_attrs_old[ + metric.name + ], + ) + def test_uninstrument_after_instrument(self): self.client().simulate_get(path="/hello") spans = self.memory_exporter.get_finished_spans() @@ -345,47 +529,119 @@ def test_falcon_metrics(self): ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) + def test_falcon_metric_values_new_semconv(self): + number_data_point_seen = False + histogram_data_point_seen = False + + start = default_timer() + self.client().simulate_get("/hello/756") + duration = max(default_timer() - start, 0) + + metrics_list = self.memory_metrics_reader.get_metrics_data() + for resource_metric in metrics_list.resource_metrics: + for scope_metric in resource_metric.scope_metrics: + for metric in scope_metric.metrics: + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + histogram_data_point_seen = True + self.assertAlmostEqual( + duration, point.sum, delta=10 + ) + if isinstance(point, NumberDataPoint): + self.assertEqual(point.value, 0) + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, + _recommended_metrics_attrs_new[metric.name], + ) + + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + + def test_falcon_metric_values_both_semconv(self): + number_data_point_seen = False + histogram_data_point_seen = False + + start = default_timer() + self.client().simulate_get("/hello/756") + duration_s = default_timer() - start + + metrics_list = self.memory_metrics_reader.get_metrics_data() + + # pylint: disable=too-many-nested-blocks + for resource_metric in metrics_list.resource_metrics: + for scope_metric in resource_metric.scope_metrics: + for metric in scope_metric.metrics: + if metric.unit == "ms": + self.assertEqual(metric.name, "http.server.duration") + elif metric.unit == "s": + self.assertEqual( + metric.name, "http.server.request.duration" + ) + else: + self.assertEqual( + metric.name, "http.server.active_requests" + ) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + if metric.unit == "ms": + self.assertAlmostEqual( + max(round(duration_s * 1000), 0), + point.sum, + delta=10, + ) + elif metric.unit == "s": + self.assertAlmostEqual( + max(duration_s, 0), point.sum, delta=10 + ) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + self.assertEqual(point.value, 0) + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, + _recommended_metrics_attrs_both[metric.name], + ) + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + def test_falcon_metric_values(self): - expected_duration_attributes = { - "http.method": "GET", - "http.host": "falconframework.org", - "http.scheme": "http", - "http.flavor": "1.1", - "http.server_name": "falconframework.org", - "net.host.port": 80, - "net.host.name": "falconframework.org", - "http.status_code": 404, - } - expected_requests_count_attributes = { - "http.method": "GET", - "http.host": "falconframework.org", - "http.scheme": "http", - "http.flavor": "1.1", - "http.server_name": "falconframework.org", - } + number_data_point_seen = False + histogram_data_point_seen = False + start = default_timer() self.client().simulate_get("/hello/756") duration = max(round((default_timer() - start) * 1000), 0) + metrics_list = self.memory_metrics_reader.get_metrics_data() for resource_metric in metrics_list.resource_metrics: for scope_metric in resource_metric.scope_metrics: for metric in scope_metric.metrics: + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) for point in list(metric.data.data_points): if isinstance(point, HistogramDataPoint): - self.assertDictEqual( - expected_duration_attributes, - dict(point.attributes), - ) self.assertEqual(point.count, 1) + histogram_data_point_seen = True self.assertAlmostEqual( duration, point.sum, delta=10 ) if isinstance(point, NumberDataPoint): - self.assertDictEqual( - expected_requests_count_attributes, - dict(point.attributes), - ) self.assertEqual(point.value, 0) + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, + _recommended_metrics_attrs_old[metric.name], + ) + + self.assertTrue(number_data_point_seen and histogram_data_point_seen) def test_metric_uninstrument(self): self.client().simulate_request(method="POST", path="/hello/756") From 5219242eafa5dff08fb2ff855860d6772a43364b Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Mon, 13 Jan 2025 21:32:16 +0000 Subject: [PATCH 323/335] Support PEP 561 to `opentelemetry-instrumentation-wsgi` (#3129) --- CHANGELOG.md | 2 + .../instrumentation/wsgi/__init__.py | 124 +++++++++++------- .../instrumentation/wsgi/package.py | 3 +- .../instrumentation/wsgi/py.typed | 0 .../src/opentelemetry/util/http/__init__.py | 10 +- 5 files changed, 87 insertions(+), 52 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 0848cf9f7a..ea1a44b574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3148](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3148)) - add support to Python 3.13 ([#3134](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3134)) +- `opentelemetry-opentelemetry-wsgi` Add `py.typed` file to enable PEP 561 + ([#3129](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3129)) - `opentelemetry-util-http` Add `py.typed` file to enable PEP 561 ([#3127](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3127)) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index bd3b2d18db..a0a2ce9a35 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -97,15 +97,22 @@ def GET(self): .. code-block:: python + from wsgiref.types import WSGIEnvironment, StartResponse + from opentelemetry.instrumentation.wsgi import OpenTelemetryMiddleware + + def app(environ: WSGIEnvironment, start_response: StartResponse): + start_response("200 OK", [("Content-Type", "text/plain"), ("Content-Length", "13")]) + return [b"Hello, World!"] + def request_hook(span: Span, environ: WSGIEnvironment): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_request_hook", "some-value") - def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_headers: List): + def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_headers: list[tuple[str, str]]): if span and span.is_recording(): span.set_attribute("custom_user_attribute_from_response_hook", "some-value") - OpenTelemetryMiddleware(request_hook=request_hook, response_hook=response_hook) + OpenTelemetryMiddleware(app, request_hook=request_hook, response_hook=response_hook) Capture HTTP request and response headers ***************************************** @@ -207,10 +214,12 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he --- """ +from __future__ import annotations + import functools -import typing import wsgiref.util as wsgiref_util from timeit import default_timer +from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, TypeVar, cast from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( @@ -240,7 +249,7 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he ) from opentelemetry.instrumentation.utils import _start_internal_or_server_span from opentelemetry.instrumentation.wsgi.version import __version__ -from opentelemetry.metrics import get_meter +from opentelemetry.metrics import MeterProvider, get_meter from opentelemetry.propagators.textmap import Getter from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.metrics import MetricInstruments @@ -248,6 +257,7 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he HTTP_SERVER_REQUEST_DURATION, ) from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.trace import TracerProvider from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import ( OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, @@ -262,15 +272,23 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he sanitize_method, ) +if TYPE_CHECKING: + from wsgiref.types import StartResponse, WSGIApplication, WSGIEnvironment + + +T = TypeVar("T") +RequestHook = Callable[[trace.Span, "WSGIEnvironment"], None] +ResponseHook = Callable[ + [trace.Span, "WSGIEnvironment", str, "list[tuple[str, str]]"], None +] + _HTTP_VERSION_PREFIX = "HTTP/" _CARRIER_KEY_PREFIX = "HTTP_" _CARRIER_KEY_PREFIX_LEN = len(_CARRIER_KEY_PREFIX) -class WSGIGetter(Getter[dict]): - def get( - self, carrier: dict, key: str - ) -> typing.Optional[typing.List[str]]: +class WSGIGetter(Getter[Dict[str, Any]]): + def get(self, carrier: dict[str, Any], key: str) -> list[str] | None: """Getter implementation to retrieve a HTTP header value from the PEP3333-conforming WSGI environ @@ -287,7 +305,7 @@ def get( return [value] return None - def keys(self, carrier): + def keys(self, carrier: dict[str, Any]): return [ key[_CARRIER_KEY_PREFIX_LEN:].lower().replace("_", "-") for key in carrier @@ -298,26 +316,19 @@ def keys(self, carrier): wsgi_getter = WSGIGetter() -def setifnotnone(dic, key, value): - if value is not None: - dic[key] = value - - # pylint: disable=too-many-branches - - def collect_request_attributes( - environ, - sem_conv_opt_in_mode=_StabilityMode.DEFAULT, + environ: WSGIEnvironment, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): """Collects HTTP request attributes from the PEP3333-conforming WSGI environ and returns a dictionary to be used as span creation attributes. """ - result = {} + result: dict[str, str | None] = {} _set_http_method( result, environ.get("REQUEST_METHOD", ""), - sanitize_method(environ.get("REQUEST_METHOD", "")), + sanitize_method(cast(str, environ.get("REQUEST_METHOD", ""))), sem_conv_opt_in_mode, ) # old semconv v1.12.0 @@ -385,7 +396,7 @@ def collect_request_attributes( return result -def collect_custom_request_headers_attributes(environ): +def collect_custom_request_headers_attributes(environ: WSGIEnvironment): """Returns custom HTTP request headers which are configured by the user from the PEP3333-conforming WSGI environ to be used as span creation attributes as described in the specification https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-request-and-response-headers @@ -411,7 +422,9 @@ def collect_custom_request_headers_attributes(environ): ) -def collect_custom_response_headers_attributes(response_headers): +def collect_custom_response_headers_attributes( + response_headers: list[tuple[str, str]], +): """Returns custom HTTP response headers which are configured by the user from the PEP3333-conforming WSGI environ as described in the specification https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-request-and-response-headers @@ -422,7 +435,7 @@ def collect_custom_response_headers_attributes(response_headers): OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS ) ) - response_headers_dict = {} + response_headers_dict: dict[str, str] = {} if response_headers: for key, val in response_headers: key = key.lower() @@ -440,7 +453,8 @@ def collect_custom_response_headers_attributes(response_headers): ) -def _parse_status_code(resp_status): +# TODO: Used only on the `opentelemetry-instrumentation-pyramid` package - It can be moved there. +def _parse_status_code(resp_status: str) -> int | None: status_code, _ = resp_status.split(" ", 1) try: return int(status_code) @@ -449,7 +463,7 @@ def _parse_status_code(resp_status): def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT + req_attrs, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT ): return _filter_semconv_active_request_count_attr( req_attrs, @@ -460,7 +474,8 @@ def _parse_active_request_count_attrs( def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT + req_attrs: dict[str, str | None], + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): return _filter_semconv_duration_attrs( req_attrs, @@ -471,11 +486,11 @@ def _parse_duration_attrs( def add_response_attributes( - span, - start_response_status, - response_headers, - duration_attrs=None, - sem_conv_opt_in_mode=_StabilityMode.DEFAULT, + span: trace.Span, + start_response_status: str, + response_headers: list[tuple[str, str]], + duration_attrs: dict[str, str | None] | None = None, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): # pylint: disable=unused-argument """Adds HTTP response attributes to span using the arguments passed to a PEP3333-conforming start_response callable. @@ -497,7 +512,7 @@ def add_response_attributes( ) -def get_default_span_name(environ): +def get_default_span_name(environ: WSGIEnvironment) -> str: """ Default span name is the HTTP method and URL path, or just the method. https://github.com/open-telemetry/opentelemetry-specification/pull/3165 @@ -508,10 +523,12 @@ def get_default_span_name(environ): Returns: The span name. """ - method = sanitize_method(environ.get("REQUEST_METHOD", "").strip()) + method = sanitize_method( + cast(str, environ.get("REQUEST_METHOD", "")).strip() + ) if method == "_OTHER": return "HTTP" - path = environ.get("PATH_INFO", "").strip() + path = cast(str, environ.get("PATH_INFO", "")).strip() if method and path: return f"{method} {path}" return method @@ -538,11 +555,11 @@ class OpenTelemetryMiddleware: def __init__( self, - wsgi, - request_hook=None, - response_hook=None, - tracer_provider=None, - meter_provider=None, + wsgi: WSGIApplication, + request_hook: RequestHook | None = None, + response_hook: ResponseHook | None = None, + tracer_provider: TracerProvider | None = None, + meter_provider: MeterProvider | None = None, ): # initialize semantic conventions opt-in if needed _OpenTelemetrySemanticConventionStability._initialize() @@ -589,14 +606,19 @@ def __init__( @staticmethod def _create_start_response( - span, - start_response, - response_hook, - duration_attrs, - sem_conv_opt_in_mode, + span: trace.Span, + start_response: StartResponse, + response_hook: Callable[[str, list[tuple[str, str]]], None] | None, + duration_attrs: dict[str, str | None], + sem_conv_opt_in_mode: _StabilityMode, ): @functools.wraps(start_response) - def _start_response(status, response_headers, *args, **kwargs): + def _start_response( + status: str, + response_headers: list[tuple[str, str]], + *args: Any, + **kwargs: Any, + ): add_response_attributes( span, status, @@ -617,7 +639,9 @@ def _start_response(status, response_headers, *args, **kwargs): return _start_response # pylint: disable=too-many-branches - def __call__(self, environ, start_response): + def __call__( + self, environ: WSGIEnvironment, start_response: StartResponse + ): """The WSGI application Args: @@ -699,7 +723,9 @@ def __call__(self, environ, start_response): # Put this in a subfunction to not delay the call to the wrapped # WSGI application (instrumentation should change the application # behavior as little as possible). -def _end_span_after_iterating(iterable, span, token): +def _end_span_after_iterating( + iterable: Iterable[T], span: trace.Span, token: object +) -> Iterable[T]: try: with trace.use_span(span): yield from iterable @@ -713,10 +739,8 @@ def _end_span_after_iterating(iterable, span, token): # TODO: inherit from opentelemetry.instrumentation.propagators.Setter - - class ResponsePropagationSetter: - def set(self, carrier, key, value): # pylint: disable=no-self-use + def set(self, carrier: list[tuple[str, T]], key: str, value: T): # pylint: disable=no-self-use carrier.append((key, value)) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/package.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/package.py index 1bb8350a06..2dbb19055f 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/package.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/package.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations -_instruments = tuple() +_instruments: tuple[str, ...] = tuple() _supports_metrics = True diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/py.typed b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index c7dd9f7b06..71a6403a7d 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -19,7 +19,7 @@ from re import IGNORECASE as RE_IGNORECASE from re import compile as re_compile from re import search -from typing import Callable, Iterable +from typing import Callable, Iterable, overload from urllib.parse import urlparse, urlunparse from opentelemetry.semconv.trace import SpanAttributes @@ -191,6 +191,14 @@ def normalise_response_header_name(header: str) -> str: return f"http.response.header.{key}" +@overload +def sanitize_method(method: str) -> str: ... + + +@overload +def sanitize_method(method: None) -> None: ... + + def sanitize_method(method: str | None) -> str | None: if method is None: return None From c59b514cdadfe062c69f8e055d7c1aa4b56dc92e Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:42:32 -0500 Subject: [PATCH 324/335] Fix component owner workflow permissions (#3165) --- .github/workflows/component-owners.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/component-owners.yml b/.github/workflows/component-owners.yml index 824e39c370..f0068701f7 100644 --- a/.github/workflows/component-owners.yml +++ b/.github/workflows/component-owners.yml @@ -10,6 +10,10 @@ jobs: run_self: runs-on: ubuntu-latest name: Auto Assign Owners + permissions: + contents: read # to read changed files + issues: write # to read/write issue assignees + pull-requests: write # to read/write PR reviewers # Don't fail tests if this workflow fails. Some pending issues: # - https://github.com/dyladan/component-owners/issues/8 continue-on-error: true From e54256ddb7d5ef5b40ffff0f594d1f77a6c757ce Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 14 Jan 2025 16:28:11 +0000 Subject: [PATCH 325/335] Support PEP 561 to `opentelemetry-instrumentation-urllib` (#3131) * Support PEP 561 to `opentelemetry-instrumentation-urllib` * add future --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../instrumentation/urllib/__init__.py | 54 +++++++++++-------- .../instrumentation/urllib/package.py | 3 +- .../instrumentation/urllib/py.typed | 0 .../instrumentation/urllib/version.py | 2 - 5 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index ea1a44b574..6e40e73270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3100)) - Add support to database stability opt-in in `_semconv` utilities and add tests ([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111)) +- `opentelemetry-instrumentation-urllib` Add `py.typed` file to enable PEP 561 + ([#3131](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3131)) - `opentelemetry-opentelemetry-pymongo` Add `py.typed` file to enable PEP 561 ([#3136](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3136)) - `opentelemetry-opentelemetry-requests` Add `py.typed` file to enable PEP 561 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index 9fe9996ba4..a80e6d0700 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -43,17 +43,24 @@ .. code:: python - # `request_obj` is an instance of urllib.request.Request - def request_hook(span, request_obj): + from http.client import HTTPResponse + from urllib.request import Request + + from opentelemetry.instrumentation.urllib import URLLibInstrumentor + from opentelemetry.trace import Span + + + def request_hook(span: Span, request: Request): pass - # `request_obj` is an instance of urllib.request.Request - # `response` is an instance of http.client.HTTPResponse - def response_hook(span, request_obj, response) + + def response_hook(span: Span, request: Request, response: HTTPResponse): pass - URLLibInstrumentor.instrument( - request_hook=request_hook, response_hook=response_hook) + + URLLibInstrumentor().instrument( + request_hook=request_hook, + response_hook=response_hook ) Exclude lists @@ -74,12 +81,14 @@ def response_hook(span, request_obj, response) --- """ +from __future__ import annotations + import functools import types import typing from http import client from timeit import default_timer -from typing import Collection, Dict +from typing import Any, Collection from urllib.request import ( # pylint: disable=no-name-in-module,import-error OpenerDirector, Request, @@ -107,7 +116,7 @@ def response_hook(span, request_obj, response) is_http_instrumentation_enabled, suppress_http_instrumentation, ) -from opentelemetry.metrics import Histogram, get_meter +from opentelemetry.metrics import Histogram, Meter, get_meter from opentelemetry.propagate import inject from opentelemetry.semconv._incubating.metrics.http_metrics import ( HTTP_CLIENT_REQUEST_BODY_SIZE, @@ -121,7 +130,7 @@ def response_hook(span, request_obj, response) HTTP_CLIENT_REQUEST_DURATION, ) from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.trace import Span, SpanKind, get_tracer +from opentelemetry.trace import Span, SpanKind, Tracer, get_tracer from opentelemetry.util.http import ( ExcludeList, get_excluded_urls, @@ -129,6 +138,7 @@ def response_hook(span, request_obj, response) remove_url_credentials, sanitize_method, ) +from opentelemetry.util.types import Attributes _excluded_urls_from_env = get_excluded_urls("URLLIB") @@ -146,7 +156,7 @@ class URLLibInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Instruments urllib module Args: @@ -194,7 +204,7 @@ def _instrument(self, **kwargs): sem_conv_opt_in_mode=sem_conv_opt_in_mode, ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): _uninstrument() def uninstrument_opener(self, opener: OpenerDirector): # pylint: disable=no-self-use @@ -204,11 +214,11 @@ def uninstrument_opener(self, opener: OpenerDirector): # pylint: disable=no-sel # pylint: disable=too-many-statements def _instrument( - tracer, - histograms: Dict[str, Histogram], + tracer: Tracer, + histograms: dict[str, Histogram], request_hook: _RequestHookT = None, response_hook: _ResponseHookT = None, - excluded_urls: ExcludeList = None, + excluded_urls: ExcludeList | None = None, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ): """Enables tracing of all requests calls that go through @@ -345,7 +355,7 @@ def _uninstrument(): _uninstrument_from(OpenerDirector) -def _uninstrument_from(instr_root, restore_as_bound_func=False): +def _uninstrument_from(instr_root, restore_as_bound_func: bool = False): instr_func_name = "open" instr_func = getattr(instr_root, instr_func_name) if not getattr( @@ -371,7 +381,7 @@ def _get_span_name(method: str) -> str: def _set_status_code_attribute( span: Span, status_code: int, - metric_attributes: dict = None, + metric_attributes: dict[str, Any] | None = None, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ) -> None: status_code_str = str(status_code) @@ -394,8 +404,8 @@ def _set_status_code_attribute( def _create_client_histograms( - meter, sem_conv_opt_in_mode=_StabilityMode.DEFAULT -) -> Dict[str, Histogram]: + meter: Meter, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT +) -> dict[str, Histogram]: histograms = {} if _report_old(sem_conv_opt_in_mode): histograms[MetricInstruments.HTTP_CLIENT_DURATION] = ( @@ -436,9 +446,9 @@ def _create_client_histograms( def _record_histograms( - histograms: Dict[str, Histogram], - metric_attributes_old: dict, - metric_attributes_new: dict, + histograms: dict[str, Histogram], + metric_attributes_old: Attributes, + metric_attributes_new: Attributes, request_size: int, response_size: int, duration_s: float, diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py index 1bb8350a06..2dbb19055f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/package.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations -_instruments = tuple() +_instruments: tuple[str, ...] = tuple() _supports_metrics = True diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/py.typed b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index c3c9026f93..6e2923f0db 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -13,5 +13,3 @@ # limitations under the License. __version__ = "0.51b0.dev" - -_instruments = tuple() From 52871b82b6afc3545609d3740620a6c4d4edf7ab Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 14 Jan 2025 17:27:35 +0000 Subject: [PATCH 326/335] Add type hints to HTTPX (#3098) --- .../instrumentation/httpx/__init__.py | 143 +++++++++--------- .../instrumentation/httpx/py.typed | 0 2 files changed, 73 insertions(+), 70 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/py.typed diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index 27bb3d639d..ba4e5b4fd4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -230,15 +230,13 @@ async def async_response_hook(span, request, response): NETWORK_PEER_ADDRESS, NETWORK_PEER_PORT, ) -from opentelemetry.trace import SpanKind, TracerProvider, get_tracer +from opentelemetry.trace import SpanKind, Tracer, TracerProvider, get_tracer from opentelemetry.trace.span import Span from opentelemetry.trace.status import StatusCode from opentelemetry.util.http import remove_url_credentials, sanitize_method _logger = logging.getLogger(__name__) -URL = typing.Tuple[bytes, bytes, typing.Optional[int], bytes] -Headers = typing.List[typing.Tuple[bytes, bytes]] RequestHook = typing.Callable[[Span, "RequestInfo"], None] ResponseHook = typing.Callable[[Span, "RequestInfo", "ResponseInfo"], None] AsyncRequestHook = typing.Callable[ @@ -253,17 +251,15 @@ class RequestInfo(typing.NamedTuple): method: bytes url: httpx.URL headers: httpx.Headers | None - stream: typing.Optional[ - typing.Union[httpx.SyncByteStream, httpx.AsyncByteStream] - ] - extensions: typing.Optional[dict] + stream: httpx.SyncByteStream | httpx.AsyncByteStream | None + extensions: dict[str, typing.Any] | None class ResponseInfo(typing.NamedTuple): status_code: int headers: httpx.Headers | None - stream: typing.Iterable[bytes] - extensions: typing.Optional[dict] + stream: httpx.SyncByteStream | httpx.AsyncByteStream + extensions: dict[str, typing.Any] | None def _get_default_span_name(method: str) -> str: @@ -274,11 +270,19 @@ def _get_default_span_name(method: str) -> str: return method -def _prepare_headers(headers: typing.Optional[Headers]) -> httpx.Headers: +def _prepare_headers(headers: httpx.Headers | None) -> httpx.Headers: return httpx.Headers(headers) -def _extract_parameters(args, kwargs): +def _extract_parameters( + args: tuple[typing.Any, ...], kwargs: dict[str, typing.Any] +) -> tuple[ + bytes, + httpx.URL, + httpx.Headers | None, + httpx.SyncByteStream | httpx.AsyncByteStream | None, + dict[str, typing.Any], +]: if isinstance(args[0], httpx.Request): # In httpx >= 0.20.0, handle_request receives a Request object request: httpx.Request = args[0] @@ -311,10 +315,15 @@ def _inject_propagation_headers(headers, args, kwargs): def _extract_response( - response: typing.Union[ - httpx.Response, typing.Tuple[int, Headers, httpx.SyncByteStream, dict] - ], -) -> typing.Tuple[int, Headers, httpx.SyncByteStream, dict, str]: + response: httpx.Response + | tuple[int, httpx.Headers, httpx.SyncByteStream, dict[str, typing.Any]], +) -> tuple[ + int, + httpx.Headers, + httpx.SyncByteStream | httpx.AsyncByteStream, + dict[str, typing.Any], + str, +]: if isinstance(response, httpx.Response): status_code = response.status_code headers = response.headers @@ -331,8 +340,8 @@ def _extract_response( def _apply_request_client_attributes_to_span( - span_attributes: dict, - url: typing.Union[str, URL, httpx.URL], + span_attributes: dict[str, typing.Any], + url: str | httpx.URL, method_original: str, semconv: _StabilityMode, ): @@ -407,9 +416,9 @@ class SyncOpenTelemetryTransport(httpx.BaseTransport): def __init__( self, transport: httpx.BaseTransport, - tracer_provider: typing.Optional[TracerProvider] = None, - request_hook: typing.Optional[RequestHook] = None, - response_hook: typing.Optional[ResponseHook] = None, + tracer_provider: TracerProvider | None = None, + request_hook: RequestHook | None = None, + response_hook: ResponseHook | None = None, ): _OpenTelemetrySemanticConventionStability._initialize() self._sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( @@ -426,27 +435,27 @@ def __init__( self._request_hook = request_hook self._response_hook = response_hook - def __enter__(self) -> "SyncOpenTelemetryTransport": + def __enter__(self) -> SyncOpenTelemetryTransport: self._transport.__enter__() return self def __exit__( self, - exc_type: typing.Optional[typing.Type[BaseException]] = None, - exc_value: typing.Optional[BaseException] = None, - traceback: typing.Optional[TracebackType] = None, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, ) -> None: self._transport.__exit__(exc_type, exc_value, traceback) # pylint: disable=R0914 def handle_request( self, - *args, - **kwargs, - ) -> typing.Union[ - typing.Tuple[int, "Headers", httpx.SyncByteStream, dict], - httpx.Response, - ]: + *args: typing.Any, + **kwargs: typing.Any, + ) -> ( + tuple[int, httpx.Headers, httpx.SyncByteStream, dict[str, typing.Any]] + | httpx.Response + ): """Add request info to span.""" if not is_http_instrumentation_enabled(): return self._transport.handle_request(*args, **kwargs) @@ -532,9 +541,9 @@ class AsyncOpenTelemetryTransport(httpx.AsyncBaseTransport): def __init__( self, transport: httpx.AsyncBaseTransport, - tracer_provider: typing.Optional[TracerProvider] = None, - request_hook: typing.Optional[AsyncRequestHook] = None, - response_hook: typing.Optional[AsyncResponseHook] = None, + tracer_provider: TracerProvider | None = None, + request_hook: AsyncRequestHook | None = None, + response_hook: AsyncResponseHook | None = None, ): _OpenTelemetrySemanticConventionStability._initialize() self._sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( @@ -557,19 +566,19 @@ async def __aenter__(self) -> "AsyncOpenTelemetryTransport": async def __aexit__( self, - exc_type: typing.Optional[typing.Type[BaseException]] = None, - exc_value: typing.Optional[BaseException] = None, - traceback: typing.Optional[TracebackType] = None, + exc_type: typing.Type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: TracebackType | None = None, ) -> None: await self._transport.__aexit__(exc_type, exc_value, traceback) # pylint: disable=R0914 async def handle_async_request( - self, *args, **kwargs - ) -> typing.Union[ - typing.Tuple[int, "Headers", httpx.AsyncByteStream, dict], - httpx.Response, - ]: + self, *args: typing.Any, **kwargs: typing.Any + ) -> ( + tuple[int, httpx.Headers, httpx.AsyncByteStream, dict[str, typing.Any]] + | httpx.Response + ): """Add request info to span.""" if not is_http_instrumentation_enabled(): return await self._transport.handle_async_request(*args, **kwargs) @@ -653,7 +662,7 @@ class HTTPXClientInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> typing.Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: typing.Any): """Instruments httpx Client and AsyncClient Args: @@ -716,20 +725,20 @@ def _instrument(self, **kwargs): ), ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: typing.Any): unwrap(httpx.HTTPTransport, "handle_request") unwrap(httpx.AsyncHTTPTransport, "handle_async_request") @staticmethod def _handle_request_wrapper( # pylint: disable=too-many-locals - wrapped, - instance, - args, - kwargs, - tracer, - sem_conv_opt_in_mode, - request_hook, - response_hook, + wrapped: typing.Callable[..., typing.Any], + instance: httpx.HTTPTransport, + args: tuple[typing.Any, ...], + kwargs: dict[str, typing.Any], + tracer: Tracer, + sem_conv_opt_in_mode: _StabilityMode, + request_hook: RequestHook, + response_hook: ResponseHook, ): if not is_http_instrumentation_enabled(): return wrapped(*args, **kwargs) @@ -796,14 +805,14 @@ def _handle_request_wrapper( # pylint: disable=too-many-locals @staticmethod async def _handle_async_request_wrapper( # pylint: disable=too-many-locals - wrapped, - instance, - args, - kwargs, - tracer, - sem_conv_opt_in_mode, - async_request_hook, - async_response_hook, + wrapped: typing.Callable[..., typing.Awaitable[typing.Any]], + instance: httpx.AsyncHTTPTransport, + args: tuple[typing.Any, ...], + kwargs: dict[str, typing.Any], + tracer: Tracer, + sem_conv_opt_in_mode: _StabilityMode, + async_request_hook: AsyncRequestHook, + async_response_hook: AsyncResponseHook, ): if not is_http_instrumentation_enabled(): return await wrapped(*args, **kwargs) @@ -872,14 +881,10 @@ async def _handle_async_request_wrapper( # pylint: disable=too-many-locals @classmethod def instrument_client( cls, - client: typing.Union[httpx.Client, httpx.AsyncClient], - tracer_provider: TracerProvider = None, - request_hook: typing.Union[ - typing.Optional[RequestHook], typing.Optional[AsyncRequestHook] - ] = None, - response_hook: typing.Union[ - typing.Optional[ResponseHook], typing.Optional[AsyncResponseHook] - ] = None, + client: httpx.Client | httpx.AsyncClient, + tracer_provider: TracerProvider | None = None, + request_hook: RequestHook | AsyncRequestHook | None = None, + response_hook: ResponseHook | AsyncResponseHook | None = None, ) -> None: """Instrument httpx Client or AsyncClient @@ -977,9 +982,7 @@ def instrument_client( client._is_instrumented_by_opentelemetry = True @staticmethod - def uninstrument_client( - client: typing.Union[httpx.Client, httpx.AsyncClient], - ): + def uninstrument_client(client: httpx.Client | httpx.AsyncClient) -> None: """Disables instrumentation for the given client instance Args: diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/py.typed b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/py.typed new file mode 100644 index 0000000000..e69de29bb2 From 07c97eac380d2f86f09a95851fb6c38182537d05 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Wed, 15 Jan 2025 16:30:01 +0000 Subject: [PATCH 327/335] Add type hints to `psycopg` (#3067) * Add type hints to Psycopg * fix tests * fix * Add psycopg.Connection to nitpick * Add py.typed * add psycopg to nitpick again * add psycopg to nitpick again * move py.typed to the right folder --------- Co-authored-by: Riccardo Magliocchetti --- docs/nitpick-exceptions.ini | 2 + .../instrumentation/psycopg/__init__.py | 69 +++++++++++-------- .../instrumentation/psycopg/package.py | 4 +- .../instrumentation/psycopg/py.typed | 0 .../tests/test_psycopg_integration.py | 4 +- 5 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/py.typed diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index b1fcdd5342..bf120765c9 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -41,6 +41,8 @@ py-class= callable Consumer confluent_kafka.Message + psycopg.Connection + psycopg.AsyncConnection ObjectProxy any= diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py index 81390ed48f..38a6264c6d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py @@ -137,27 +137,28 @@ --- """ +from __future__ import annotations + import logging -import typing -from typing import Collection +from typing import Any, Callable, Collection, TypeVar import psycopg # pylint: disable=import-self -from psycopg import ( - AsyncCursor as pg_async_cursor, # pylint: disable=import-self,no-name-in-module -) -from psycopg import ( - Cursor as pg_cursor, # pylint: disable=no-name-in-module,import-self -) from psycopg.sql import Composed # pylint: disable=no-name-in-module from opentelemetry.instrumentation import dbapi from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.psycopg.package import _instruments from opentelemetry.instrumentation.psycopg.version import __version__ +from opentelemetry.trace import TracerProvider _logger = logging.getLogger(__name__) _OTEL_CURSOR_FACTORY_KEY = "_otel_orig_cursor_factory" +ConnectionT = TypeVar( + "ConnectionT", psycopg.Connection, psycopg.AsyncConnection +) +CursorT = TypeVar("CursorT", psycopg.Cursor, psycopg.AsyncCursor) + class PsycopgInstrumentor(BaseInstrumentor): _CONNECTION_ATTRIBUTES = { @@ -172,7 +173,7 @@ class PsycopgInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Integrate with PostgreSQL Psycopg library. Psycopg: http://initd.org/psycopg/ """ @@ -223,7 +224,7 @@ def _instrument(self, **kwargs): enable_attribute_commenter=enable_attribute_commenter, ) - def _uninstrument(self, **kwargs): + def _uninstrument(self, **kwargs: Any): """ "Disable Psycopg instrumentation""" dbapi.unwrap_connect(psycopg, "connect") # pylint: disable=no-member dbapi.unwrap_connect( @@ -237,7 +238,9 @@ def _uninstrument(self, **kwargs): # TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql @staticmethod - def instrument_connection(connection, tracer_provider=None): + def instrument_connection( + connection: ConnectionT, tracer_provider: TracerProvider | None = None + ) -> ConnectionT: """Enable instrumentation in a psycopg connection. Args: @@ -269,7 +272,7 @@ def instrument_connection(connection, tracer_provider=None): # TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql @staticmethod - def uninstrument_connection(connection): + def uninstrument_connection(connection: ConnectionT) -> ConnectionT: connection.cursor_factory = getattr( connection, _OTEL_CURSOR_FACTORY_KEY, None ) @@ -281,9 +284,9 @@ def uninstrument_connection(connection): class DatabaseApiIntegration(dbapi.DatabaseApiIntegration): def wrapped_connection( self, - connect_method: typing.Callable[..., typing.Any], - args: typing.Tuple[typing.Any, typing.Any], - kwargs: typing.Dict[typing.Any, typing.Any], + connect_method: Callable[..., Any], + args: tuple[Any, Any], + kwargs: dict[Any, Any], ): """Add object proxy to connection object.""" base_cursor_factory = kwargs.pop("cursor_factory", None) @@ -299,9 +302,9 @@ def wrapped_connection( class DatabaseApiAsyncIntegration(dbapi.DatabaseApiIntegration): async def wrapped_connection( self, - connect_method: typing.Callable[..., typing.Any], - args: typing.Tuple[typing.Any, typing.Any], - kwargs: typing.Dict[typing.Any, typing.Any], + connect_method: Callable[..., Any], + args: tuple[Any, Any], + kwargs: dict[Any, Any], ): """Add object proxy to connection object.""" base_cursor_factory = kwargs.pop("cursor_factory", None) @@ -317,7 +320,7 @@ async def wrapped_connection( class CursorTracer(dbapi.CursorTracer): - def get_operation_name(self, cursor, args): + def get_operation_name(self, cursor: CursorT, args: list[Any]) -> str: if not args: return "" @@ -332,7 +335,7 @@ def get_operation_name(self, cursor, args): return "" - def get_statement(self, cursor, args): + def get_statement(self, cursor: CursorT, args: list[Any]) -> str: if not args: return "" @@ -342,7 +345,11 @@ def get_statement(self, cursor, args): return statement -def _new_cursor_factory(db_api=None, base_factory=None, tracer_provider=None): +def _new_cursor_factory( + db_api: DatabaseApiIntegration | None = None, + base_factory: type[psycopg.Cursor] | None = None, + tracer_provider: TracerProvider | None = None, +): if not db_api: db_api = DatabaseApiIntegration( __name__, @@ -352,21 +359,21 @@ def _new_cursor_factory(db_api=None, base_factory=None, tracer_provider=None): tracer_provider=tracer_provider, ) - base_factory = base_factory or pg_cursor + base_factory = base_factory or psycopg.Cursor _cursor_tracer = CursorTracer(db_api) class TracedCursorFactory(base_factory): - def execute(self, *args, **kwargs): + def execute(self, *args: Any, **kwargs: Any): return _cursor_tracer.traced_execution( self, super().execute, *args, **kwargs ) - def executemany(self, *args, **kwargs): + def executemany(self, *args: Any, **kwargs: Any): return _cursor_tracer.traced_execution( self, super().executemany, *args, **kwargs ) - def callproc(self, *args, **kwargs): + def callproc(self, *args: Any, **kwargs: Any): return _cursor_tracer.traced_execution( self, super().callproc, *args, **kwargs ) @@ -375,7 +382,9 @@ def callproc(self, *args, **kwargs): def _new_cursor_async_factory( - db_api=None, base_factory=None, tracer_provider=None + db_api: DatabaseApiAsyncIntegration | None = None, + base_factory: type[psycopg.AsyncCursor] | None = None, + tracer_provider: TracerProvider | None = None, ): if not db_api: db_api = DatabaseApiAsyncIntegration( @@ -385,21 +394,21 @@ def _new_cursor_async_factory( version=__version__, tracer_provider=tracer_provider, ) - base_factory = base_factory or pg_async_cursor + base_factory = base_factory or psycopg.AsyncCursor _cursor_tracer = CursorTracer(db_api) class TracedCursorAsyncFactory(base_factory): - async def execute(self, *args, **kwargs): + async def execute(self, *args: Any, **kwargs: Any): return await _cursor_tracer.traced_execution( self, super().execute, *args, **kwargs ) - async def executemany(self, *args, **kwargs): + async def executemany(self, *args: Any, **kwargs: Any): return await _cursor_tracer.traced_execution( self, super().executemany, *args, **kwargs ) - async def callproc(self, *args, **kwargs): + async def callproc(self, *args: Any, **kwargs: Any): return await _cursor_tracer.traced_execution( self, super().callproc, *args, **kwargs ) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/package.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/package.py index 635edfb4db..a3ee72d1ae 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/package.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/package.py @@ -11,6 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations - -_instruments = ("psycopg >= 3.1.0",) +_instruments: tuple[str, ...] = ("psycopg >= 3.1.0",) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/py.typed b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py index 4ddaad9174..6c9bcf2d4b 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py @@ -132,10 +132,10 @@ class PostgresqlIntegrationTestMixin: def setUp(self): super().setUp() self.cursor_mock = mock.patch( - "opentelemetry.instrumentation.psycopg.pg_cursor", MockCursor + "opentelemetry.instrumentation.psycopg.psycopg.Cursor", MockCursor ) self.cursor_async_mock = mock.patch( - "opentelemetry.instrumentation.psycopg.pg_async_cursor", + "opentelemetry.instrumentation.psycopg.psycopg.AsyncCursor", MockAsyncCursor, ) self.connection_mock = mock.patch("psycopg.connect", MockConnection) From a716949d1c28341b2fb9af75f43b541ddeac9335 Mon Sep 17 00:00:00 2001 From: Drew Robbins Date: Thu, 16 Jan 2025 07:24:35 +0900 Subject: [PATCH 328/335] Add metrics to the Python OpenAI instrumentation (#3180) --- .../CHANGELOG.md | 1 + .../README.rst | 45 ++++- .../instrumentation/openai_v2/__init__.py | 18 +- .../instrumentation/openai_v2/instruments.py | 11 + .../instrumentation/openai_v2/patch.py | 107 +++++++++- .../test_async_chat_completion_metrics.yaml | 133 ++++++++++++ .../test_chat_completion_metrics.yaml | 135 +++++++++++++ .../tests/conftest.py | 83 +++++++- .../tests/test_chat_completions.py | 49 ++++- .../tests/test_chat_metrics.py | 190 ++++++++++++++++++ 10 files changed, 763 insertions(+), 9 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_metrics.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_metrics.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 4644ee3dc5..ed27904e63 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add example to `opentelemetry-instrumentation-openai-v2` ([#3006](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3006)) - Support for `AsyncOpenAI/AsyncCompletions` ([#2984](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2984)) +- Add metrics ([#3180](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3180)) ## Version 2.0b0 (2024-11-08) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst index d2cb0b5724..c402b30bc0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst @@ -7,7 +7,8 @@ OpenTelemetry OpenAI Instrumentation :target: https://pypi.org/project/opentelemetry-instrumentation-openai-v2/ This library allows tracing LLM requests and logging of messages made by the -`OpenAI Python API library `_. +`OpenAI Python API library `_. It also captures +the duration of the operations and the number of tokens used as metrics. Installation @@ -74,6 +75,48 @@ To uninstrument clients, call the uninstrument method: # Uninstrument all clients OpenAIInstrumentor().uninstrument() +Bucket Boundaries +----------------- + +This section describes the explicit bucket boundaries for metrics such as token usage and operation duration, and guides users to create Views to implement them according to the semantic conventions. + +The bucket boundaries are defined as follows: + +- For `gen_ai.client.token.usage`: [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864] +- For `gen_ai.client.operation.duration`: [0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48, 40.96, 81.92] + +To implement these bucket boundaries, you can create Views in your OpenTelemetry SDK setup. Here is an example: + +.. code-block:: python + + from opentelemetry.sdk.metrics import MeterProvider, View + from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader + from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter + from opentelemetry.sdk.metrics.aggregation import ExplicitBucketHistogramAggregation + + views = [ + View( + instrument_name="gen_ai.client.token.usage", + aggregation=ExplicitBucketHistogramAggregation([1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864]), + ), + View( + instrument_name="gen_ai.client.operation.duration", + aggregation=ExplicitBucketHistogramAggregation([0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48, 40.96, 81.92]), + ), + ] + + metric_exporter = OTLPMetricExporter(endpoint="http://localhost:4317") + metric_reader = PeriodicExportingMetricReader(metric_exporter) + provider = MeterProvider( + metric_readers=[metric_reader], + views=views + ) + + from opentelemetry.sdk.metrics import set_meter_provider + set_meter_provider(provider) + +For more details, refer to the `OpenTelemetry GenAI Metrics documentation `_. + References ---------- * `OpenTelemetry OpenAI Instrumentation `_ diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py index ee3bbfdb73..ab4b6f9d7b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -49,13 +49,18 @@ from opentelemetry.instrumentation.openai_v2.package import _instruments from opentelemetry.instrumentation.openai_v2.utils import is_content_enabled from opentelemetry.instrumentation.utils import unwrap +from opentelemetry.metrics import get_meter from opentelemetry.semconv.schemas import Schemas from opentelemetry.trace import get_tracer +from .instruments import Instruments from .patch import async_chat_completions_create, chat_completions_create class OpenAIInstrumentor(BaseInstrumentor): + def __init__(self): + self._meter = None + def instrumentation_dependencies(self) -> Collection[str]: return _instruments @@ -75,12 +80,21 @@ def _instrument(self, **kwargs): schema_url=Schemas.V1_28_0.value, event_logger_provider=event_logger_provider, ) + meter_provider = kwargs.get("meter_provider") + self._meter = get_meter( + __name__, + "", + meter_provider, + schema_url=Schemas.V1_28_0.value, + ) + + instruments = Instruments(self._meter) wrap_function_wrapper( module="openai.resources.chat.completions", name="Completions.create", wrapper=chat_completions_create( - tracer, event_logger, is_content_enabled() + tracer, event_logger, instruments, is_content_enabled() ), ) @@ -88,7 +102,7 @@ def _instrument(self, **kwargs): module="openai.resources.chat.completions", name="AsyncCompletions.create", wrapper=async_chat_completions_create( - tracer, event_logger, is_content_enabled() + tracer, event_logger, instruments, is_content_enabled() ), ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py new file mode 100644 index 0000000000..d1e184ac84 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py @@ -0,0 +1,11 @@ +from opentelemetry.semconv._incubating.metrics import gen_ai_metrics + + +class Instruments: + def __init__(self, meter): + self.operation_duration_histogram = ( + gen_ai_metrics.create_gen_ai_client_operation_duration(meter) + ) + self.token_usage_histogram = ( + gen_ai_metrics.create_gen_ai_client_token_usage(meter) + ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index cd284473ce..307b312fca 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -13,6 +13,7 @@ # limitations under the License. +from timeit import default_timer from typing import Optional from openai import Stream @@ -21,8 +22,12 @@ from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) from opentelemetry.trace import Span, SpanKind, Tracer +from .instruments import Instruments from .utils import ( choice_to_event, get_llm_request_attributes, @@ -34,7 +39,10 @@ def chat_completions_create( - tracer: Tracer, event_logger: EventLogger, capture_content: bool + tracer: Tracer, + event_logger: EventLogger, + instruments: Instruments, + capture_content: bool, ): """Wrap the `create` method of the `ChatCompletion` class to trace it.""" @@ -54,6 +62,9 @@ def traced_method(wrapped, instance, args, kwargs): message_to_event(message, capture_content) ) + start = default_timer() + result = None + error_type = None try: result = wrapped(*args, **kwargs) if is_streaming(kwargs): @@ -69,14 +80,27 @@ def traced_method(wrapped, instance, args, kwargs): return result except Exception as error: + error_type = type(error).__qualname__ handle_span_exception(span, error) raise + finally: + duration = max((default_timer() - start), 0) + _record_metrics( + instruments, + duration, + result, + span_attributes, + error_type, + ) return traced_method def async_chat_completions_create( - tracer: Tracer, event_logger: EventLogger, capture_content: bool + tracer: Tracer, + event_logger: EventLogger, + instruments: Instruments, + capture_content: bool, ): """Wrap the `create` method of the `AsyncChatCompletion` class to trace it.""" @@ -96,6 +120,9 @@ async def traced_method(wrapped, instance, args, kwargs): message_to_event(message, capture_content) ) + start = default_timer() + result = None + error_type = None try: result = await wrapped(*args, **kwargs) if is_streaming(kwargs): @@ -111,12 +138,88 @@ async def traced_method(wrapped, instance, args, kwargs): return result except Exception as error: + error_type = type(error).__qualname__ handle_span_exception(span, error) raise + finally: + duration = max((default_timer() - start), 0) + _record_metrics( + instruments, + duration, + result, + span_attributes, + error_type, + ) return traced_method +def _record_metrics( + instruments: Instruments, + duration: float, + result, + span_attributes: dict, + error_type: Optional[str], +): + common_attributes = { + GenAIAttributes.GEN_AI_OPERATION_NAME: GenAIAttributes.GenAiOperationNameValues.CHAT.value, + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.OPENAI.value, + GenAIAttributes.GEN_AI_REQUEST_MODEL: span_attributes[ + GenAIAttributes.GEN_AI_REQUEST_MODEL + ], + } + + if error_type: + common_attributes["error.type"] = error_type + + if result and getattr(result, "model", None): + common_attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] = result.model + + if result and getattr(result, "service_tier", None): + common_attributes[ + GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER + ] = result.service_tier + + if result and getattr(result, "system_fingerprint", None): + common_attributes["gen_ai.openai.response.system_fingerprint"] = ( + result.system_fingerprint + ) + + if ServerAttributes.SERVER_ADDRESS in span_attributes: + common_attributes[ServerAttributes.SERVER_ADDRESS] = span_attributes[ + ServerAttributes.SERVER_ADDRESS + ] + + if ServerAttributes.SERVER_PORT in span_attributes: + common_attributes[ServerAttributes.SERVER_PORT] = span_attributes[ + ServerAttributes.SERVER_PORT + ] + + instruments.operation_duration_histogram.record( + duration, + attributes=common_attributes, + ) + + if result and getattr(result, "usage", None): + input_attributes = { + **common_attributes, + GenAIAttributes.GEN_AI_TOKEN_TYPE: GenAIAttributes.GenAiTokenTypeValues.INPUT.value, + } + instruments.token_usage_histogram.record( + result.usage.prompt_tokens, + attributes=input_attributes, + ) + + completion_attributes = { + **common_attributes, + GenAIAttributes.GEN_AI_TOKEN_TYPE: GenAIAttributes.GenAiTokenTypeValues.COMPLETION.value, + } + instruments.token_usage_histogram.record( + result.usage.completion_tokens, + attributes=completion_attributes, + ) + + def _set_response_attributes( span, result, event_logger: EventLogger, capture_content: bool ): diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_metrics.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_metrics.yaml new file mode 100644 index 0000000000..e771e93cbe --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_async_chat_completion_metrics.yaml @@ -0,0 +1,133 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9R2E7Yhb2e7bj4Xl0qm9s3J42Y", + "object": "chat.completion", + "created": 1731456237, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "service_tier": "default", + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80679a8311a6-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:03:58 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '796' + openai-organization: test_openai_org_id + openai-processing-ms: + - '359' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999978' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_41ea134c1fc450d4ca4cf8d0c6a7c53a + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_metrics.yaml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_metrics.yaml new file mode 100644 index 0000000000..1c6c11c858 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_metrics.yaml @@ -0,0 +1,135 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMQRl3A3DXL9FWCK9tnGRcKIO7q", + "object": "chat.completion", + "created": 1731368630, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "service_tier": "default", + "usage": { + "prompt_tokens": 12, + "completion_tokens": 5, + "total_tokens": 17, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e122593ff368bc8-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:50 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '765' + openai-organization: test_openai_org_id + openai-processing-ms: + - '287' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '199977' + x-ratelimit-reset-requests: + - 8.64s + x-ratelimit-reset-tokens: + - 6ms + x-request-id: + - req_58cff97afd0e7c0bba910ccf0b044a6f + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 18e6582dff..51521dbadd 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -17,6 +17,17 @@ InMemoryLogExporter, SimpleLogRecordProcessor, ) +from opentelemetry.sdk.metrics import ( + Histogram, + MeterProvider, +) +from opentelemetry.sdk.metrics.export import ( + InMemoryMetricReader, +) +from opentelemetry.sdk.metrics.view import ( + ExplicitBucketHistogramAggregation, + View, +) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( @@ -36,6 +47,12 @@ def fixture_log_exporter(): yield exporter +@pytest.fixture(scope="function", name="metric_reader") +def fixture_metric_reader(): + exporter = InMemoryMetricReader() + yield exporter + + @pytest.fixture(scope="function", name="tracer_provider") def fixture_tracer_provider(span_exporter): provider = TracerProvider() @@ -52,6 +69,62 @@ def fixture_event_logger_provider(log_exporter): return event_logger_provider +@pytest.fixture(scope="function", name="meter_provider") +def fixture_meter_provider(metric_reader): + token_usage_histogram_view = View( + instrument_type=Histogram, + instrument_name="gen_ai.client.token.usage", + aggregation=ExplicitBucketHistogramAggregation( + boundaries=[ + 1, + 4, + 16, + 64, + 256, + 1024, + 4096, + 16384, + 65536, + 262144, + 1048576, + 4194304, + 16777216, + 67108864, + ] + ), + ) + + duration_histogram_view = View( + instrument_type=Histogram, + instrument_name="gen_ai.client.operation.duration", + aggregation=ExplicitBucketHistogramAggregation( + boundaries=[ + 0.01, + 0.02, + 0.04, + 0.08, + 0.16, + 0.32, + 0.64, + 1.28, + 2.56, + 5.12, + 10.24, + 20.48, + 40.96, + 81.92, + ] + ), + ) + + meter_provider = MeterProvider( + metric_readers=[metric_reader], + views=[token_usage_histogram_view, duration_histogram_view], + ) + + return meter_provider + + @pytest.fixture(autouse=True) def environment(): if not os.getenv("OPENAI_API_KEY"): @@ -83,7 +156,9 @@ def vcr_config(): @pytest.fixture(scope="function") -def instrument_no_content(tracer_provider, event_logger_provider): +def instrument_no_content( + tracer_provider, event_logger_provider, meter_provider +): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"} ) @@ -92,6 +167,7 @@ def instrument_no_content(tracer_provider, event_logger_provider): instrumentor.instrument( tracer_provider=tracer_provider, event_logger_provider=event_logger_provider, + meter_provider=meter_provider, ) yield instrumentor @@ -100,7 +176,9 @@ def instrument_no_content(tracer_provider, event_logger_provider): @pytest.fixture(scope="function") -def instrument_with_content(tracer_provider, event_logger_provider): +def instrument_with_content( + tracer_provider, event_logger_provider, meter_provider +): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} ) @@ -108,6 +186,7 @@ def instrument_with_content(tracer_provider, event_logger_provider): instrumentor.instrument( tracer_provider=tracer_provider, event_logger_provider=event_logger_provider, + meter_provider=meter_provider, ) yield instrumentor diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index 4677b7cb95..9685903603 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -32,6 +32,7 @@ from opentelemetry.semconv._incubating.attributes import ( server_attributes as ServerAttributes, ) +from opentelemetry.semconv._incubating.metrics import gen_ai_metrics @pytest.mark.vcr() @@ -94,7 +95,9 @@ def test_chat_completion_no_content( assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) -def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): +def test_chat_completion_bad_endpoint( + span_exporter, metric_reader, instrument_no_content +): llm_model_value = "gpt-4o-mini" messages_value = [{"role": "user", "content": "Say this is a test"}] @@ -116,10 +119,31 @@ def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] ) + metrics = metric_reader.get_metrics_data().resource_metrics + assert len(metrics) == 1 + + metric_data = metrics[0].scope_metrics[0].metrics + duration_metric = next( + ( + m + for m in metric_data + if m.name == gen_ai_metrics.GEN_AI_CLIENT_OPERATION_DURATION + ), + None, + ) + assert duration_metric is not None + assert duration_metric.data.data_points[0].sum > 0 + assert ( + duration_metric.data.data_points[0].attributes[ + ErrorAttributes.ERROR_TYPE + ] + == "APIConnectionError" + ) + @pytest.mark.vcr() def test_chat_completion_404( - span_exporter, openai_client, instrument_no_content + span_exporter, openai_client, metric_reader, instrument_no_content ): llm_model_value = "this-model-does-not-exist" messages_value = [{"role": "user", "content": "Say this is a test"}] @@ -135,6 +159,27 @@ def test_chat_completion_404( assert_all_attributes(spans[0], llm_model_value) assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + metrics = metric_reader.get_metrics_data().resource_metrics + assert len(metrics) == 1 + + metric_data = metrics[0].scope_metrics[0].metrics + duration_metric = next( + ( + m + for m in metric_data + if m.name == gen_ai_metrics.GEN_AI_CLIENT_OPERATION_DURATION + ), + None, + ) + assert duration_metric is not None + assert duration_metric.data.data_points[0].sum > 0 + assert ( + duration_metric.data.data_points[0].attributes[ + ErrorAttributes.ERROR_TYPE + ] + == "NotFoundError" + ) + @pytest.mark.vcr() def test_chat_completion_extra_params( diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py new file mode 100644 index 0000000000..d0f7c5a596 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py @@ -0,0 +1,190 @@ +import pytest + +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) +from opentelemetry.semconv._incubating.metrics import gen_ai_metrics + + +def assert_all_metric_attributes(data_point): + assert GenAIAttributes.GEN_AI_OPERATION_NAME in data_point.attributes + assert ( + data_point.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + == GenAIAttributes.GenAiOperationNameValues.CHAT.value + ) + assert GenAIAttributes.GEN_AI_SYSTEM in data_point.attributes + assert ( + data_point.attributes[GenAIAttributes.GEN_AI_SYSTEM] + == GenAIAttributes.GenAiSystemValues.OPENAI.value + ) + assert GenAIAttributes.GEN_AI_REQUEST_MODEL in data_point.attributes + assert ( + data_point.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + == "gpt-4o-mini" + ) + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL in data_point.attributes + assert ( + data_point.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + == "gpt-4o-mini-2024-07-18" + ) + assert "gen_ai.openai.response.system_fingerprint" in data_point.attributes + assert ( + data_point.attributes["gen_ai.openai.response.system_fingerprint"] + == "fp_0ba0d124f1" + ) + assert ( + GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER + in data_point.attributes + ) + assert ( + data_point.attributes[ + GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER + ] + == "default" + ) + assert ( + data_point.attributes[ServerAttributes.SERVER_ADDRESS] + == "api.openai.com" + ) + + +@pytest.mark.vcr() +def test_chat_completion_metrics( + metric_reader, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + metrics = metric_reader.get_metrics_data().resource_metrics + assert len(metrics) == 1 + + metric_data = metrics[0].scope_metrics[0].metrics + assert len(metric_data) == 2 + + duration_metric = next( + ( + m + for m in metric_data + if m.name == gen_ai_metrics.GEN_AI_CLIENT_OPERATION_DURATION + ), + None, + ) + assert duration_metric is not None + assert duration_metric.data.data_points[0].sum > 0 + assert_all_metric_attributes(duration_metric.data.data_points[0]) + + token_usage_metric = next( + ( + m + for m in metric_data + if m.name == gen_ai_metrics.GEN_AI_CLIENT_TOKEN_USAGE + ), + None, + ) + assert token_usage_metric is not None + + input_token_usage = next( + ( + d + for d in token_usage_metric.data.data_points + if d.attributes[GenAIAttributes.GEN_AI_TOKEN_TYPE] + == GenAIAttributes.GenAiTokenTypeValues.INPUT.value + ), + None, + ) + assert input_token_usage is not None + assert input_token_usage.sum == 12 + # assert against buckets [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864] + assert input_token_usage.bucket_counts[2] == 1 + assert_all_metric_attributes(input_token_usage) + + output_token_usage = next( + ( + d + for d in token_usage_metric.data.data_points + if d.attributes[GenAIAttributes.GEN_AI_TOKEN_TYPE] + == GenAIAttributes.GenAiTokenTypeValues.COMPLETION.value + ), + None, + ) + assert output_token_usage is not None + assert output_token_usage.sum == 5 + # assert against buckets [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864] + assert output_token_usage.bucket_counts[2] == 1 + assert_all_metric_attributes(output_token_usage) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_metrics( + metric_reader, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + metrics = metric_reader.get_metrics_data().resource_metrics + assert len(metrics) == 1 + + metric_data = metrics[0].scope_metrics[0].metrics + assert len(metric_data) == 2 + + duration_metric = next( + ( + m + for m in metric_data + if m.name == gen_ai_metrics.GEN_AI_CLIENT_OPERATION_DURATION + ), + None, + ) + assert duration_metric is not None + assert duration_metric.data.data_points[0].sum > 0 + assert_all_metric_attributes(duration_metric.data.data_points[0]) + + token_usage_metric = next( + ( + m + for m in metric_data + if m.name == gen_ai_metrics.GEN_AI_CLIENT_TOKEN_USAGE + ), + None, + ) + assert token_usage_metric is not None + + input_token_usage = next( + ( + d + for d in token_usage_metric.data.data_points + if d.attributes[GenAIAttributes.GEN_AI_TOKEN_TYPE] + == GenAIAttributes.GenAiTokenTypeValues.INPUT.value + ), + None, + ) + + assert input_token_usage is not None + assert input_token_usage.sum == 12 + assert_all_metric_attributes(input_token_usage) + + output_token_usage = next( + ( + d + for d in token_usage_metric.data.data_points + if d.attributes[GenAIAttributes.GEN_AI_TOKEN_TYPE] + == GenAIAttributes.GenAiTokenTypeValues.COMPLETION.value + ), + None, + ) + + assert output_token_usage is not None + assert output_token_usage.sum == 12 + assert_all_metric_attributes(output_token_usage) From 9d9353d4c6e9d1230a6364914eede3720f58772e Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Thu, 16 Jan 2025 14:25:35 -0500 Subject: [PATCH 329/335] Run pyright on Vertex AI instrumentation (#3184) --- .../src/opentelemetry/instrumentation/vertexai/__init__.py | 6 +++--- .../src/opentelemetry/instrumentation/vertexai/py.typed | 0 pyproject.toml | 5 ++++- tox.ini | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/py.typed diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py index b2011513a9..9437184ff0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py @@ -39,7 +39,7 @@ --- """ -from typing import Collection +from typing import Any, Collection from opentelemetry._events import get_event_logger from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -52,7 +52,7 @@ class VertexAIInstrumentor(BaseInstrumentor): def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): + def _instrument(self, **kwargs: Any): """Enable VertexAI instrumentation.""" tracer_provider = kwargs.get("tracer_provider") _tracer = get_tracer( @@ -70,5 +70,5 @@ def _instrument(self, **kwargs): ) # TODO: implemented in later PR - def _uninstrument(self, **kwargs) -> None: + def _uninstrument(self, **kwargs: Any) -> None: """TODO: implemented in later PR""" diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/py.typed b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pyproject.toml b/pyproject.toml index 6ba2e933c3..c023fc549f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,10 +48,13 @@ pythonVersion = "3.8" reportPrivateUsage = false # Ignore private attributes added by instrumentation packages. # Add progressively instrumentation packages here. include = [ - "instrumentation/opentelemetry-instrumentation-threading/**/*.py" + "instrumentation/opentelemetry-instrumentation-threading/**/*.py", + "instrumentation-genai/opentelemetry-instrumentation-vertexai/**/*.py", ] # We should also add type hints to the test suite - It helps on finding bugs. # We are excluding for now because it's easier, and more important to add to the instrumentation packages. exclude = [ "instrumentation/opentelemetry-instrumentation-threading/tests/**", + "instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/**/*.py", + "instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/**/*.py", ] diff --git a/tox.ini b/tox.ini index feeda77702..13dd9fafb6 100644 --- a/tox.ini +++ b/tox.ini @@ -994,5 +994,6 @@ deps = {[testenv]test_deps} {toxinidir}/opentelemetry-instrumentation {toxinidir}/util/opentelemetry-util-http + {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] commands = pyright From 9b217bb4ffe4b96aa0bdd3468579507461ffb183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:33:52 -0300 Subject: [PATCH 330/335] introducing tox-uv for real (#3185) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/core_contrib_test_0.yml | 180 +++---- .../core_contrib_test.yml.j2 | 2 +- .../src/generate_workflows_lib/lint.yml.j2 | 2 +- .../src/generate_workflows_lib/misc.yml.j2 | 2 +- .../src/generate_workflows_lib/test.yml.j2 | 2 +- .github/workflows/lint_0.yml | 124 ++--- .github/workflows/misc_0.yml | 16 +- .github/workflows/test_0.yml | 500 +++++++++--------- .github/workflows/test_1.yml | 500 +++++++++--------- .github/workflows/test_2.yml | 204 +++---- CONTRIBUTING.md | 10 +- tox.ini | 2 + 12 files changed, 776 insertions(+), 768 deletions(-) diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index 6c0616e0a6..7ab737c657 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -36,7 +36,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-openai-v2-0 -- -ra @@ -58,7 +58,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-openai-v2-1 -- -ra @@ -80,7 +80,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-vertexai-0 -- -ra @@ -102,7 +102,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-vertexai-1 -- -ra @@ -124,7 +124,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-resource-detector-container -- -ra @@ -146,7 +146,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-resource-detector-azure-0 -- -ra @@ -168,7 +168,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-resource-detector-azure-1 -- -ra @@ -190,7 +190,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-sdk-extension-aws-0 -- -ra @@ -212,7 +212,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-sdk-extension-aws-1 -- -ra @@ -234,7 +234,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-distro -- -ra @@ -256,7 +256,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-opentelemetry-instrumentation -- -ra @@ -278,7 +278,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiohttp-client -- -ra @@ -300,7 +300,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiohttp-server -- -ra @@ -322,7 +322,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiopg -- -ra @@ -344,7 +344,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aws-lambda -- -ra @@ -366,7 +366,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-botocore -- -ra @@ -388,7 +388,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-boto3sqs -- -ra @@ -410,7 +410,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-django-0 -- -ra @@ -432,7 +432,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-django-1 -- -ra @@ -454,7 +454,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-django-2 -- -ra @@ -476,7 +476,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-dbapi -- -ra @@ -498,7 +498,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-boto -- -ra @@ -520,7 +520,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-click -- -ra @@ -542,7 +542,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra @@ -564,7 +564,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra @@ -586,7 +586,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra @@ -608,7 +608,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-0 -- -ra @@ -630,7 +630,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-1 -- -ra @@ -652,7 +652,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-2 -- -ra @@ -674,7 +674,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-3 -- -ra @@ -696,7 +696,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-fastapi -- -ra @@ -718,7 +718,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-flask-0 -- -ra @@ -740,7 +740,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-flask-1 -- -ra @@ -762,7 +762,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-flask-2 -- -ra @@ -784,7 +784,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-urllib -- -ra @@ -806,7 +806,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-urllib3-0 -- -ra @@ -828,7 +828,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-urllib3-1 -- -ra @@ -850,7 +850,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-requests -- -ra @@ -872,7 +872,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-starlette -- -ra @@ -894,7 +894,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-jinja2 -- -ra @@ -916,7 +916,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-logging -- -ra @@ -938,7 +938,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-exporter-richconsole -- -ra @@ -960,7 +960,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-exporter-prometheus-remote-write -- -ra @@ -982,7 +982,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-mysql-0 -- -ra @@ -1004,7 +1004,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-mysql-1 -- -ra @@ -1026,7 +1026,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-mysqlclient -- -ra @@ -1048,7 +1048,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-psycopg2 -- -ra @@ -1070,7 +1070,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-psycopg -- -ra @@ -1092,7 +1092,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra @@ -1114,7 +1114,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra @@ -1136,7 +1136,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra @@ -1158,7 +1158,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra @@ -1180,7 +1180,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra @@ -1202,7 +1202,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymongo -- -ra @@ -1224,7 +1224,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymysql -- -ra @@ -1246,7 +1246,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pyramid -- -ra @@ -1268,7 +1268,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-asgi -- -ra @@ -1290,7 +1290,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-asyncpg -- -ra @@ -1312,7 +1312,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sqlite3 -- -ra @@ -1334,7 +1334,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-wsgi -- -ra @@ -1356,7 +1356,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-grpc-0 -- -ra @@ -1378,7 +1378,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-grpc-1 -- -ra @@ -1400,7 +1400,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra @@ -1422,7 +1422,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sqlalchemy-2 -- -ra @@ -1444,7 +1444,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-redis -- -ra @@ -1466,7 +1466,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-remoulade -- -ra @@ -1488,7 +1488,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-celery -- -ra @@ -1510,7 +1510,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-system-metrics -- -ra @@ -1532,7 +1532,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-threading -- -ra @@ -1554,7 +1554,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-tornado -- -ra @@ -1576,7 +1576,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-tortoiseorm -- -ra @@ -1598,7 +1598,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-httpx-0 -- -ra @@ -1620,7 +1620,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-httpx-1 -- -ra @@ -1642,7 +1642,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-util-http -- -ra @@ -1664,7 +1664,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-propagator-aws-xray-0 -- -ra @@ -1686,7 +1686,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-propagator-aws-xray-1 -- -ra @@ -1708,7 +1708,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-propagator-ot-trace -- -ra @@ -1730,7 +1730,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sio-pika-0 -- -ra @@ -1752,7 +1752,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sio-pika-1 -- -ra @@ -1774,7 +1774,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-0 -- -ra @@ -1796,7 +1796,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-1 -- -ra @@ -1818,7 +1818,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-2 -- -ra @@ -1840,7 +1840,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-3 -- -ra @@ -1862,7 +1862,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiokafka -- -ra @@ -1884,7 +1884,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-kafka-python -- -ra @@ -1906,7 +1906,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-kafka-pythonng -- -ra @@ -1928,7 +1928,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-confluent-kafka -- -ra @@ -1950,7 +1950,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-asyncio -- -ra @@ -1972,7 +1972,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-cassandra -- -ra @@ -1994,7 +1994,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-processor-baggage -- -ra diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 index 5553caf8eb..f34b8e7941 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 @@ -37,7 +37,7 @@ jobs: architecture: "x64" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e {{ job_data.tox_env }} -- -ra diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 index 225387e352..ef779bc5c9 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 @@ -30,7 +30,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e {{ job_data.tox_env }} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index 9972507bb6..b6af56048f 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -57,7 +57,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e {{ job_data }} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 index e5168470d8..e5d15beb4d 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 @@ -30,7 +30,7 @@ jobs: python-version: "{{ job_data.python_version }}" - name: Install tox - run: pip install tox + run: pip install tox-uv {%- if job_data.os == "windows-latest" %} - name: Configure git to support long filenames diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index e36a6a2ad2..34db823570 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -29,7 +29,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-openai-v2 @@ -47,7 +47,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-vertexai @@ -65,7 +65,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-resource-detector-container @@ -83,7 +83,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-resource-detector-azure @@ -101,7 +101,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-sdk-extension-aws @@ -119,7 +119,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-distro @@ -137,7 +137,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-opentelemetry-instrumentation @@ -155,7 +155,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-aiohttp-client @@ -173,7 +173,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-aiohttp-server @@ -191,7 +191,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-aiopg @@ -209,7 +209,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-aws-lambda @@ -227,7 +227,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-botocore @@ -245,7 +245,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-boto3sqs @@ -263,7 +263,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-django @@ -281,7 +281,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-dbapi @@ -299,7 +299,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-boto @@ -317,7 +317,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-click @@ -335,7 +335,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-elasticsearch @@ -353,7 +353,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-falcon @@ -371,7 +371,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-fastapi @@ -389,7 +389,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-flask @@ -407,7 +407,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-urllib @@ -425,7 +425,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-urllib3 @@ -443,7 +443,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-requests @@ -461,7 +461,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-starlette @@ -479,7 +479,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-jinja2 @@ -497,7 +497,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-logging @@ -515,7 +515,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-exporter-richconsole @@ -533,7 +533,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-exporter-prometheus-remote-write @@ -551,7 +551,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-mysql @@ -569,7 +569,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-mysqlclient @@ -587,7 +587,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-psycopg2 @@ -605,7 +605,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-psycopg @@ -623,7 +623,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-pymemcache @@ -641,7 +641,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-pymongo @@ -659,7 +659,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-pymysql @@ -677,7 +677,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-pyramid @@ -695,7 +695,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-asgi @@ -713,7 +713,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-asyncpg @@ -731,7 +731,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-sqlite3 @@ -749,7 +749,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-wsgi @@ -767,7 +767,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-grpc @@ -785,7 +785,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-sqlalchemy @@ -803,7 +803,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-redis @@ -821,7 +821,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-remoulade @@ -839,7 +839,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-celery @@ -857,7 +857,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-system-metrics @@ -875,7 +875,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-threading @@ -893,7 +893,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-tornado @@ -911,7 +911,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-tortoiseorm @@ -929,7 +929,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-httpx @@ -947,7 +947,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-util-http @@ -965,7 +965,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-propagator-aws-xray @@ -983,7 +983,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-propagator-ot-trace @@ -1001,7 +1001,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-sio-pika @@ -1019,7 +1019,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-aio-pika @@ -1037,7 +1037,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-aiokafka @@ -1055,7 +1055,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-kafka-python @@ -1073,7 +1073,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-confluent-kafka @@ -1091,7 +1091,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-asyncio @@ -1109,7 +1109,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-instrumentation-cassandra @@ -1127,7 +1127,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e lint-processor-baggage diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 422669b86f..2e59715660 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -29,7 +29,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e spellcheck @@ -47,7 +47,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e docker-tests @@ -67,7 +67,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e docs @@ -85,7 +85,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e generate @@ -109,7 +109,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e generate-workflows @@ -130,7 +130,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e shellcheck @@ -148,7 +148,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e ruff @@ -166,7 +166,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e typecheck diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index e651777907..bbfb5a6865 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -29,7 +29,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-openai-v2-0 -- -ra @@ -47,7 +47,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-openai-v2-1 -- -ra @@ -65,7 +65,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-openai-v2-0 -- -ra @@ -83,7 +83,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-openai-v2-1 -- -ra @@ -101,7 +101,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-openai-v2-0 -- -ra @@ -119,7 +119,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-openai-v2-1 -- -ra @@ -137,7 +137,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-openai-v2-0 -- -ra @@ -155,7 +155,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-openai-v2-1 -- -ra @@ -173,7 +173,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-openai-v2-0 -- -ra @@ -191,7 +191,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-openai-v2-1 -- -ra @@ -209,7 +209,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-openai-v2-0 -- -ra @@ -227,7 +227,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-openai-v2-1 -- -ra @@ -245,7 +245,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-openai-v2-0 -- -ra @@ -263,7 +263,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-openai-v2-1 -- -ra @@ -281,7 +281,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-vertexai-0 -- -ra @@ -299,7 +299,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-vertexai-1 -- -ra @@ -317,7 +317,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-vertexai-0 -- -ra @@ -335,7 +335,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-vertexai-1 -- -ra @@ -353,7 +353,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-vertexai-0 -- -ra @@ -371,7 +371,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-vertexai-1 -- -ra @@ -389,7 +389,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-vertexai-0 -- -ra @@ -407,7 +407,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-vertexai-1 -- -ra @@ -425,7 +425,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-vertexai-0 -- -ra @@ -443,7 +443,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-vertexai-1 -- -ra @@ -461,7 +461,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-vertexai-0 -- -ra @@ -479,7 +479,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-vertexai-1 -- -ra @@ -497,7 +497,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-resource-detector-container -- -ra @@ -515,7 +515,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-resource-detector-container -- -ra @@ -533,7 +533,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-resource-detector-container -- -ra @@ -551,7 +551,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-resource-detector-container -- -ra @@ -569,7 +569,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-resource-detector-container -- -ra @@ -587,7 +587,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-resource-detector-container -- -ra @@ -605,7 +605,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-resource-detector-container -- -ra @@ -623,7 +623,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-resource-detector-azure-0 -- -ra @@ -641,7 +641,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-resource-detector-azure-1 -- -ra @@ -659,7 +659,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-resource-detector-azure-0 -- -ra @@ -677,7 +677,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-resource-detector-azure-1 -- -ra @@ -695,7 +695,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-resource-detector-azure-0 -- -ra @@ -713,7 +713,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-resource-detector-azure-1 -- -ra @@ -731,7 +731,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-resource-detector-azure-0 -- -ra @@ -749,7 +749,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-resource-detector-azure-1 -- -ra @@ -767,7 +767,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-resource-detector-azure-0 -- -ra @@ -785,7 +785,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-resource-detector-azure-1 -- -ra @@ -803,7 +803,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-resource-detector-azure-0 -- -ra @@ -821,7 +821,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-resource-detector-azure-1 -- -ra @@ -839,7 +839,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-resource-detector-azure-0 -- -ra @@ -857,7 +857,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-resource-detector-azure-1 -- -ra @@ -875,7 +875,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-sdk-extension-aws-0 -- -ra @@ -893,7 +893,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-sdk-extension-aws-1 -- -ra @@ -911,7 +911,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-sdk-extension-aws-0 -- -ra @@ -929,7 +929,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-sdk-extension-aws-1 -- -ra @@ -947,7 +947,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-sdk-extension-aws-0 -- -ra @@ -965,7 +965,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-sdk-extension-aws-1 -- -ra @@ -983,7 +983,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-sdk-extension-aws-0 -- -ra @@ -1001,7 +1001,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-sdk-extension-aws-1 -- -ra @@ -1019,7 +1019,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-sdk-extension-aws-0 -- -ra @@ -1037,7 +1037,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-sdk-extension-aws-1 -- -ra @@ -1055,7 +1055,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-sdk-extension-aws-0 -- -ra @@ -1073,7 +1073,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-sdk-extension-aws-1 -- -ra @@ -1091,7 +1091,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra @@ -1109,7 +1109,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra @@ -1127,7 +1127,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-distro -- -ra @@ -1145,7 +1145,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-distro -- -ra @@ -1163,7 +1163,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-distro -- -ra @@ -1181,7 +1181,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-distro -- -ra @@ -1199,7 +1199,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-distro -- -ra @@ -1217,7 +1217,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-distro -- -ra @@ -1235,7 +1235,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-distro -- -ra @@ -1253,7 +1253,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-opentelemetry-instrumentation -- -ra @@ -1271,7 +1271,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-opentelemetry-instrumentation -- -ra @@ -1289,7 +1289,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-opentelemetry-instrumentation -- -ra @@ -1307,7 +1307,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-opentelemetry-instrumentation -- -ra @@ -1325,7 +1325,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-opentelemetry-instrumentation -- -ra @@ -1343,7 +1343,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-opentelemetry-instrumentation -- -ra @@ -1361,7 +1361,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-opentelemetry-instrumentation -- -ra @@ -1379,7 +1379,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiohttp-client -- -ra @@ -1397,7 +1397,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aiohttp-client -- -ra @@ -1415,7 +1415,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aiohttp-client -- -ra @@ -1433,7 +1433,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aiohttp-client -- -ra @@ -1451,7 +1451,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aiohttp-client -- -ra @@ -1469,7 +1469,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aiohttp-client -- -ra @@ -1487,7 +1487,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra @@ -1505,7 +1505,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiohttp-server -- -ra @@ -1523,7 +1523,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aiohttp-server -- -ra @@ -1541,7 +1541,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aiohttp-server -- -ra @@ -1559,7 +1559,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aiohttp-server -- -ra @@ -1577,7 +1577,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aiohttp-server -- -ra @@ -1595,7 +1595,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aiohttp-server -- -ra @@ -1613,7 +1613,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra @@ -1631,7 +1631,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiopg -- -ra @@ -1649,7 +1649,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aiopg -- -ra @@ -1667,7 +1667,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aiopg -- -ra @@ -1685,7 +1685,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aiopg -- -ra @@ -1703,7 +1703,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aiopg -- -ra @@ -1721,7 +1721,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aiopg -- -ra @@ -1739,7 +1739,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aws-lambda -- -ra @@ -1757,7 +1757,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aws-lambda -- -ra @@ -1775,7 +1775,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aws-lambda -- -ra @@ -1793,7 +1793,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aws-lambda -- -ra @@ -1811,7 +1811,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aws-lambda -- -ra @@ -1829,7 +1829,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aws-lambda -- -ra @@ -1847,7 +1847,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra @@ -1865,7 +1865,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-botocore -- -ra @@ -1883,7 +1883,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-botocore -- -ra @@ -1901,7 +1901,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-botocore -- -ra @@ -1919,7 +1919,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-botocore -- -ra @@ -1937,7 +1937,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-botocore -- -ra @@ -1955,7 +1955,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-botocore -- -ra @@ -1973,7 +1973,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-boto3sqs -- -ra @@ -1991,7 +1991,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-boto3sqs -- -ra @@ -2009,7 +2009,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-boto3sqs -- -ra @@ -2027,7 +2027,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-boto3sqs -- -ra @@ -2045,7 +2045,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-boto3sqs -- -ra @@ -2063,7 +2063,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-boto3sqs -- -ra @@ -2081,7 +2081,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra @@ -2099,7 +2099,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-django-0 -- -ra @@ -2117,7 +2117,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-django-1 -- -ra @@ -2135,7 +2135,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-django-2 -- -ra @@ -2153,7 +2153,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-django-0 -- -ra @@ -2171,7 +2171,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-django-1 -- -ra @@ -2189,7 +2189,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-django-2 -- -ra @@ -2207,7 +2207,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-django-1 -- -ra @@ -2225,7 +2225,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-django-3 -- -ra @@ -2243,7 +2243,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-django-1 -- -ra @@ -2261,7 +2261,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-django-3 -- -ra @@ -2279,7 +2279,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-django-1 -- -ra @@ -2297,7 +2297,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-django-3 -- -ra @@ -2315,7 +2315,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-django-3 -- -ra @@ -2333,7 +2333,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-django-0 -- -ra @@ -2351,7 +2351,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-django-1 -- -ra @@ -2369,7 +2369,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-dbapi -- -ra @@ -2387,7 +2387,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-dbapi -- -ra @@ -2405,7 +2405,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-dbapi -- -ra @@ -2423,7 +2423,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-dbapi -- -ra @@ -2441,7 +2441,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-dbapi -- -ra @@ -2459,7 +2459,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-dbapi -- -ra @@ -2477,7 +2477,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-dbapi -- -ra @@ -2495,7 +2495,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-boto -- -ra @@ -2513,7 +2513,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-boto -- -ra @@ -2531,7 +2531,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-boto -- -ra @@ -2549,7 +2549,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-boto -- -ra @@ -2567,7 +2567,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-click -- -ra @@ -2585,7 +2585,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-click -- -ra @@ -2603,7 +2603,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-click -- -ra @@ -2621,7 +2621,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-click -- -ra @@ -2639,7 +2639,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-click -- -ra @@ -2657,7 +2657,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-click -- -ra @@ -2675,7 +2675,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-click -- -ra @@ -2693,7 +2693,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra @@ -2711,7 +2711,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra @@ -2729,7 +2729,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra @@ -2747,7 +2747,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra @@ -2765,7 +2765,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra @@ -2783,7 +2783,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra @@ -2801,7 +2801,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra @@ -2819,7 +2819,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra @@ -2837,7 +2837,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra @@ -2855,7 +2855,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra @@ -2873,7 +2873,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra @@ -2891,7 +2891,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra @@ -2909,7 +2909,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra @@ -2927,7 +2927,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra @@ -2945,7 +2945,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra @@ -2963,7 +2963,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra @@ -2981,7 +2981,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra @@ -2999,7 +2999,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra @@ -3017,7 +3017,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra @@ -3035,7 +3035,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra @@ -3053,7 +3053,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra @@ -3071,7 +3071,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-0 -- -ra @@ -3089,7 +3089,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-1 -- -ra @@ -3107,7 +3107,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-2 -- -ra @@ -3125,7 +3125,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-falcon-3 -- -ra @@ -3143,7 +3143,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-falcon-0 -- -ra @@ -3161,7 +3161,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-falcon-1 -- -ra @@ -3179,7 +3179,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-falcon-2 -- -ra @@ -3197,7 +3197,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-falcon-3 -- -ra @@ -3215,7 +3215,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-falcon-1 -- -ra @@ -3233,7 +3233,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-falcon-2 -- -ra @@ -3251,7 +3251,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-falcon-3 -- -ra @@ -3269,7 +3269,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-falcon-4 -- -ra @@ -3287,7 +3287,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-falcon-1 -- -ra @@ -3305,7 +3305,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-falcon-2 -- -ra @@ -3323,7 +3323,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-falcon-3 -- -ra @@ -3341,7 +3341,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-falcon-4 -- -ra @@ -3359,7 +3359,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-falcon-1 -- -ra @@ -3377,7 +3377,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-falcon-2 -- -ra @@ -3395,7 +3395,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-falcon-3 -- -ra @@ -3413,7 +3413,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-falcon-4 -- -ra @@ -3431,7 +3431,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-falcon-4 -- -ra @@ -3449,7 +3449,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra @@ -3467,7 +3467,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra @@ -3485,7 +3485,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra @@ -3503,7 +3503,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra @@ -3521,7 +3521,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra @@ -3539,7 +3539,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-fastapi -- -ra @@ -3557,7 +3557,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-fastapi -- -ra @@ -3575,7 +3575,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-fastapi -- -ra @@ -3593,7 +3593,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-fastapi -- -ra @@ -3611,7 +3611,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-fastapi -- -ra @@ -3629,7 +3629,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-fastapi -- -ra @@ -3647,7 +3647,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-fastapi -- -ra @@ -3665,7 +3665,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-flask-0 -- -ra @@ -3683,7 +3683,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-flask-1 -- -ra @@ -3701,7 +3701,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-flask-2 -- -ra @@ -3719,7 +3719,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-flask-0 -- -ra @@ -3737,7 +3737,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-flask-1 -- -ra @@ -3755,7 +3755,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-flask-2 -- -ra @@ -3773,7 +3773,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-flask-0 -- -ra @@ -3791,7 +3791,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-flask-1 -- -ra @@ -3809,7 +3809,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-flask-2 -- -ra @@ -3827,7 +3827,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-flask-0 -- -ra @@ -3845,7 +3845,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-flask-1 -- -ra @@ -3863,7 +3863,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-flask-2 -- -ra @@ -3881,7 +3881,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-flask-0 -- -ra @@ -3899,7 +3899,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-flask-1 -- -ra @@ -3917,7 +3917,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-flask-2 -- -ra @@ -3935,7 +3935,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-flask-0 -- -ra @@ -3953,7 +3953,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-flask-1 -- -ra @@ -3971,7 +3971,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-flask-2 -- -ra @@ -3989,7 +3989,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-flask-0 -- -ra @@ -4007,7 +4007,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-flask-1 -- -ra @@ -4025,7 +4025,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-urllib -- -ra @@ -4043,7 +4043,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-urllib -- -ra @@ -4061,7 +4061,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-urllib -- -ra @@ -4079,7 +4079,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-urllib -- -ra @@ -4097,7 +4097,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-urllib -- -ra @@ -4115,7 +4115,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-urllib -- -ra @@ -4133,7 +4133,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-urllib -- -ra @@ -4151,7 +4151,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-urllib3-0 -- -ra @@ -4169,7 +4169,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-urllib3-1 -- -ra @@ -4187,7 +4187,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-urllib3-0 -- -ra @@ -4205,7 +4205,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-urllib3-1 -- -ra @@ -4223,7 +4223,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-urllib3-0 -- -ra @@ -4241,7 +4241,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-urllib3-1 -- -ra @@ -4259,7 +4259,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-urllib3-0 -- -ra @@ -4277,7 +4277,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-urllib3-1 -- -ra @@ -4295,7 +4295,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-urllib3-0 -- -ra @@ -4313,7 +4313,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-urllib3-1 -- -ra @@ -4331,7 +4331,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-urllib3-0 -- -ra @@ -4349,7 +4349,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-urllib3-1 -- -ra @@ -4367,7 +4367,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra @@ -4385,7 +4385,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra @@ -4403,7 +4403,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-requests -- -ra @@ -4421,7 +4421,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-requests -- -ra @@ -4439,7 +4439,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-requests -- -ra @@ -4457,7 +4457,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-requests -- -ra @@ -4475,7 +4475,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-requests -- -ra @@ -4493,7 +4493,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-requests -- -ra @@ -4511,7 +4511,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-starlette -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index b26bb48e33..7cd1b5ed61 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -29,7 +29,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-starlette -- -ra @@ -47,7 +47,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-starlette -- -ra @@ -65,7 +65,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-starlette -- -ra @@ -83,7 +83,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-starlette -- -ra @@ -101,7 +101,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-starlette -- -ra @@ -119,7 +119,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-starlette -- -ra @@ -137,7 +137,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-jinja2 -- -ra @@ -155,7 +155,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-jinja2 -- -ra @@ -173,7 +173,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-jinja2 -- -ra @@ -191,7 +191,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-jinja2 -- -ra @@ -209,7 +209,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-jinja2 -- -ra @@ -227,7 +227,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-jinja2 -- -ra @@ -245,7 +245,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-jinja2 -- -ra @@ -263,7 +263,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-logging -- -ra @@ -281,7 +281,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-logging -- -ra @@ -299,7 +299,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-logging -- -ra @@ -317,7 +317,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-logging -- -ra @@ -335,7 +335,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-logging -- -ra @@ -353,7 +353,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-logging -- -ra @@ -371,7 +371,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-logging -- -ra @@ -389,7 +389,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-exporter-richconsole -- -ra @@ -407,7 +407,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-exporter-richconsole -- -ra @@ -425,7 +425,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-exporter-richconsole -- -ra @@ -443,7 +443,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-exporter-richconsole -- -ra @@ -461,7 +461,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-exporter-richconsole -- -ra @@ -479,7 +479,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-exporter-richconsole -- -ra @@ -497,7 +497,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-exporter-richconsole -- -ra @@ -515,7 +515,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-exporter-prometheus-remote-write -- -ra @@ -533,7 +533,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-exporter-prometheus-remote-write -- -ra @@ -551,7 +551,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-exporter-prometheus-remote-write -- -ra @@ -569,7 +569,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-exporter-prometheus-remote-write -- -ra @@ -587,7 +587,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-exporter-prometheus-remote-write -- -ra @@ -605,7 +605,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-exporter-prometheus-remote-write -- -ra @@ -623,7 +623,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra @@ -641,7 +641,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-mysql-0 -- -ra @@ -659,7 +659,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-mysql-1 -- -ra @@ -677,7 +677,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-mysql-0 -- -ra @@ -695,7 +695,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-mysql-1 -- -ra @@ -713,7 +713,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-mysql-0 -- -ra @@ -731,7 +731,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-mysql-1 -- -ra @@ -749,7 +749,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-mysql-0 -- -ra @@ -767,7 +767,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-mysql-1 -- -ra @@ -785,7 +785,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-mysql-0 -- -ra @@ -803,7 +803,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-mysql-1 -- -ra @@ -821,7 +821,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-mysql-0 -- -ra @@ -839,7 +839,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-mysql-1 -- -ra @@ -857,7 +857,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra @@ -875,7 +875,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra @@ -893,7 +893,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-mysqlclient -- -ra @@ -911,7 +911,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-mysqlclient -- -ra @@ -929,7 +929,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-mysqlclient -- -ra @@ -947,7 +947,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-mysqlclient -- -ra @@ -965,7 +965,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-mysqlclient -- -ra @@ -983,7 +983,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-mysqlclient -- -ra @@ -1001,7 +1001,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra @@ -1019,7 +1019,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-psycopg2 -- -ra @@ -1037,7 +1037,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-psycopg2 -- -ra @@ -1055,7 +1055,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-psycopg2 -- -ra @@ -1073,7 +1073,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-psycopg2 -- -ra @@ -1091,7 +1091,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-psycopg2 -- -ra @@ -1109,7 +1109,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-psycopg2 -- -ra @@ -1127,7 +1127,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-psycopg -- -ra @@ -1145,7 +1145,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-psycopg -- -ra @@ -1163,7 +1163,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-psycopg -- -ra @@ -1181,7 +1181,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-psycopg -- -ra @@ -1199,7 +1199,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-psycopg -- -ra @@ -1217,7 +1217,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-psycopg -- -ra @@ -1235,7 +1235,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-psycopg -- -ra @@ -1253,7 +1253,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-0 -- -ra @@ -1271,7 +1271,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-1 -- -ra @@ -1289,7 +1289,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-2 -- -ra @@ -1307,7 +1307,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-3 -- -ra @@ -1325,7 +1325,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymemcache-4 -- -ra @@ -1343,7 +1343,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra @@ -1361,7 +1361,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra @@ -1379,7 +1379,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra @@ -1397,7 +1397,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra @@ -1415,7 +1415,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra @@ -1433,7 +1433,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra @@ -1451,7 +1451,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra @@ -1469,7 +1469,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra @@ -1487,7 +1487,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra @@ -1505,7 +1505,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra @@ -1523,7 +1523,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra @@ -1541,7 +1541,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra @@ -1559,7 +1559,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra @@ -1577,7 +1577,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra @@ -1595,7 +1595,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra @@ -1613,7 +1613,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra @@ -1631,7 +1631,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra @@ -1649,7 +1649,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra @@ -1667,7 +1667,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra @@ -1685,7 +1685,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra @@ -1703,7 +1703,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymemcache-0 -- -ra @@ -1721,7 +1721,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymemcache-1 -- -ra @@ -1739,7 +1739,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymemcache-2 -- -ra @@ -1757,7 +1757,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymemcache-3 -- -ra @@ -1775,7 +1775,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymemcache-4 -- -ra @@ -1793,7 +1793,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra @@ -1811,7 +1811,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra @@ -1829,7 +1829,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra @@ -1847,7 +1847,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra @@ -1865,7 +1865,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra @@ -1883,7 +1883,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymongo -- -ra @@ -1901,7 +1901,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymongo -- -ra @@ -1919,7 +1919,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymongo -- -ra @@ -1937,7 +1937,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymongo -- -ra @@ -1955,7 +1955,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymongo -- -ra @@ -1973,7 +1973,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymongo -- -ra @@ -1991,7 +1991,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymongo -- -ra @@ -2009,7 +2009,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pymysql -- -ra @@ -2027,7 +2027,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pymysql -- -ra @@ -2045,7 +2045,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pymysql -- -ra @@ -2063,7 +2063,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pymysql -- -ra @@ -2081,7 +2081,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pymysql -- -ra @@ -2099,7 +2099,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-pymysql -- -ra @@ -2117,7 +2117,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pymysql -- -ra @@ -2135,7 +2135,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-pyramid -- -ra @@ -2153,7 +2153,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-pyramid -- -ra @@ -2171,7 +2171,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-pyramid -- -ra @@ -2189,7 +2189,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-pyramid -- -ra @@ -2207,7 +2207,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-pyramid -- -ra @@ -2225,7 +2225,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-pyramid -- -ra @@ -2243,7 +2243,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-asgi -- -ra @@ -2261,7 +2261,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-asgi -- -ra @@ -2279,7 +2279,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-asgi -- -ra @@ -2297,7 +2297,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-asgi -- -ra @@ -2315,7 +2315,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-asgi -- -ra @@ -2333,7 +2333,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-asgi -- -ra @@ -2351,7 +2351,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-asgi -- -ra @@ -2369,7 +2369,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-asyncpg -- -ra @@ -2387,7 +2387,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-asyncpg -- -ra @@ -2405,7 +2405,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-asyncpg -- -ra @@ -2423,7 +2423,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-asyncpg -- -ra @@ -2441,7 +2441,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-asyncpg -- -ra @@ -2459,7 +2459,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-asyncpg -- -ra @@ -2477,7 +2477,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sqlite3 -- -ra @@ -2495,7 +2495,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-sqlite3 -- -ra @@ -2513,7 +2513,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-sqlite3 -- -ra @@ -2531,7 +2531,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-sqlite3 -- -ra @@ -2549,7 +2549,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-sqlite3 -- -ra @@ -2567,7 +2567,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-sqlite3 -- -ra @@ -2585,7 +2585,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra @@ -2603,7 +2603,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-wsgi -- -ra @@ -2621,7 +2621,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-wsgi -- -ra @@ -2639,7 +2639,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-wsgi -- -ra @@ -2657,7 +2657,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-wsgi -- -ra @@ -2675,7 +2675,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-wsgi -- -ra @@ -2693,7 +2693,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-wsgi -- -ra @@ -2711,7 +2711,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-wsgi -- -ra @@ -2729,7 +2729,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-grpc-0 -- -ra @@ -2747,7 +2747,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-grpc-1 -- -ra @@ -2765,7 +2765,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-grpc-0 -- -ra @@ -2783,7 +2783,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-grpc-1 -- -ra @@ -2801,7 +2801,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-grpc-0 -- -ra @@ -2819,7 +2819,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-grpc-1 -- -ra @@ -2837,7 +2837,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-grpc-0 -- -ra @@ -2855,7 +2855,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-grpc-1 -- -ra @@ -2873,7 +2873,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-grpc-0 -- -ra @@ -2891,7 +2891,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-grpc-1 -- -ra @@ -2909,7 +2909,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-grpc-1 -- -ra @@ -2927,7 +2927,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sqlalchemy-1 -- -ra @@ -2945,7 +2945,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sqlalchemy-2 -- -ra @@ -2963,7 +2963,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra @@ -2981,7 +2981,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra @@ -2999,7 +2999,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra @@ -3017,7 +3017,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra @@ -3035,7 +3035,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra @@ -3053,7 +3053,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra @@ -3071,7 +3071,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra @@ -3089,7 +3089,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra @@ -3107,7 +3107,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-sqlalchemy-1 -- -ra @@ -3125,7 +3125,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-sqlalchemy-2 -- -ra @@ -3143,7 +3143,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra @@ -3161,7 +3161,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra @@ -3179,7 +3179,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra @@ -3197,7 +3197,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-redis -- -ra @@ -3215,7 +3215,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-redis -- -ra @@ -3233,7 +3233,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-redis -- -ra @@ -3251,7 +3251,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-redis -- -ra @@ -3269,7 +3269,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-redis -- -ra @@ -3287,7 +3287,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-redis -- -ra @@ -3305,7 +3305,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-redis -- -ra @@ -3323,7 +3323,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-remoulade -- -ra @@ -3341,7 +3341,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-remoulade -- -ra @@ -3359,7 +3359,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-remoulade -- -ra @@ -3377,7 +3377,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-remoulade -- -ra @@ -3395,7 +3395,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-remoulade -- -ra @@ -3413,7 +3413,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-remoulade -- -ra @@ -3431,7 +3431,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-celery -- -ra @@ -3449,7 +3449,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-celery -- -ra @@ -3467,7 +3467,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-celery -- -ra @@ -3485,7 +3485,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-celery -- -ra @@ -3503,7 +3503,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-celery -- -ra @@ -3521,7 +3521,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-celery -- -ra @@ -3539,7 +3539,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-celery -- -ra @@ -3557,7 +3557,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-system-metrics -- -ra @@ -3575,7 +3575,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-system-metrics -- -ra @@ -3593,7 +3593,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-system-metrics -- -ra @@ -3611,7 +3611,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-system-metrics -- -ra @@ -3629,7 +3629,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-system-metrics -- -ra @@ -3647,7 +3647,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-system-metrics -- -ra @@ -3665,7 +3665,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-system-metrics -- -ra @@ -3683,7 +3683,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-threading -- -ra @@ -3701,7 +3701,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-threading -- -ra @@ -3719,7 +3719,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-threading -- -ra @@ -3737,7 +3737,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-threading -- -ra @@ -3755,7 +3755,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-threading -- -ra @@ -3773,7 +3773,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-threading -- -ra @@ -3791,7 +3791,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-threading -- -ra @@ -3809,7 +3809,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-tornado -- -ra @@ -3827,7 +3827,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-tornado -- -ra @@ -3845,7 +3845,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-tornado -- -ra @@ -3863,7 +3863,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-tornado -- -ra @@ -3881,7 +3881,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-tornado -- -ra @@ -3899,7 +3899,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-tornado -- -ra @@ -3917,7 +3917,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-tornado -- -ra @@ -3935,7 +3935,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-tortoiseorm -- -ra @@ -3953,7 +3953,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-tortoiseorm -- -ra @@ -3971,7 +3971,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-tortoiseorm -- -ra @@ -3989,7 +3989,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-tortoiseorm -- -ra @@ -4007,7 +4007,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-tortoiseorm -- -ra @@ -4025,7 +4025,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-tortoiseorm -- -ra @@ -4043,7 +4043,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra @@ -4061,7 +4061,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-httpx-0 -- -ra @@ -4079,7 +4079,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-httpx-1 -- -ra @@ -4097,7 +4097,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-httpx-0 -- -ra @@ -4115,7 +4115,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-httpx-1 -- -ra @@ -4133,7 +4133,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-httpx-0 -- -ra @@ -4151,7 +4151,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-httpx-1 -- -ra @@ -4169,7 +4169,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-httpx-0 -- -ra @@ -4187,7 +4187,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-httpx-1 -- -ra @@ -4205,7 +4205,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-httpx-0 -- -ra @@ -4223,7 +4223,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-httpx-1 -- -ra @@ -4241,7 +4241,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-httpx-1 -- -ra @@ -4259,7 +4259,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-httpx-0 -- -ra @@ -4277,7 +4277,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-httpx-1 -- -ra @@ -4295,7 +4295,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-util-http -- -ra @@ -4313,7 +4313,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-util-http -- -ra @@ -4331,7 +4331,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-util-http -- -ra @@ -4349,7 +4349,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-util-http -- -ra @@ -4367,7 +4367,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-util-http -- -ra @@ -4385,7 +4385,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-util-http -- -ra @@ -4403,7 +4403,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-util-http -- -ra @@ -4421,7 +4421,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-propagator-aws-xray-0 -- -ra @@ -4439,7 +4439,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-propagator-aws-xray-1 -- -ra @@ -4457,7 +4457,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-propagator-aws-xray-0 -- -ra @@ -4475,7 +4475,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-propagator-aws-xray-1 -- -ra @@ -4493,7 +4493,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-propagator-aws-xray-0 -- -ra @@ -4511,7 +4511,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-propagator-aws-xray-1 -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index ceac5ac9ed..fd1dcb00e0 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -29,7 +29,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-propagator-aws-xray-0 -- -ra @@ -47,7 +47,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-propagator-aws-xray-1 -- -ra @@ -65,7 +65,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-propagator-aws-xray-0 -- -ra @@ -83,7 +83,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-propagator-aws-xray-1 -- -ra @@ -101,7 +101,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-propagator-aws-xray-0 -- -ra @@ -119,7 +119,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-propagator-aws-xray-1 -- -ra @@ -137,7 +137,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra @@ -155,7 +155,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra @@ -173,7 +173,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-propagator-ot-trace -- -ra @@ -191,7 +191,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-propagator-ot-trace -- -ra @@ -209,7 +209,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-propagator-ot-trace -- -ra @@ -227,7 +227,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-propagator-ot-trace -- -ra @@ -245,7 +245,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-propagator-ot-trace -- -ra @@ -263,7 +263,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-propagator-ot-trace -- -ra @@ -281,7 +281,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-propagator-ot-trace -- -ra @@ -299,7 +299,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sio-pika-0 -- -ra @@ -317,7 +317,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-sio-pika-1 -- -ra @@ -335,7 +335,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-sio-pika-0 -- -ra @@ -353,7 +353,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-sio-pika-1 -- -ra @@ -371,7 +371,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-sio-pika-0 -- -ra @@ -389,7 +389,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-sio-pika-1 -- -ra @@ -407,7 +407,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-sio-pika-0 -- -ra @@ -425,7 +425,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-sio-pika-1 -- -ra @@ -443,7 +443,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-sio-pika-0 -- -ra @@ -461,7 +461,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-sio-pika-1 -- -ra @@ -479,7 +479,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-sio-pika-0 -- -ra @@ -497,7 +497,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-sio-pika-1 -- -ra @@ -515,7 +515,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-sio-pika-0 -- -ra @@ -533,7 +533,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-sio-pika-1 -- -ra @@ -551,7 +551,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-0 -- -ra @@ -569,7 +569,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-1 -- -ra @@ -587,7 +587,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-2 -- -ra @@ -605,7 +605,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aio-pika-3 -- -ra @@ -623,7 +623,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra @@ -641,7 +641,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra @@ -659,7 +659,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra @@ -677,7 +677,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra @@ -695,7 +695,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra @@ -713,7 +713,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra @@ -731,7 +731,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra @@ -749,7 +749,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra @@ -767,7 +767,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra @@ -785,7 +785,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra @@ -803,7 +803,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra @@ -821,7 +821,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra @@ -839,7 +839,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra @@ -857,7 +857,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra @@ -875,7 +875,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra @@ -893,7 +893,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra @@ -911,7 +911,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aio-pika-0 -- -ra @@ -929,7 +929,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aio-pika-1 -- -ra @@ -947,7 +947,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aio-pika-2 -- -ra @@ -965,7 +965,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aio-pika-3 -- -ra @@ -983,7 +983,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra @@ -1001,7 +1001,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra @@ -1019,7 +1019,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra @@ -1037,7 +1037,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra @@ -1055,7 +1055,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-aiokafka -- -ra @@ -1073,7 +1073,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-aiokafka -- -ra @@ -1091,7 +1091,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-aiokafka -- -ra @@ -1109,7 +1109,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-aiokafka -- -ra @@ -1127,7 +1127,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-aiokafka -- -ra @@ -1145,7 +1145,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-aiokafka -- -ra @@ -1163,7 +1163,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-aiokafka -- -ra @@ -1181,7 +1181,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-kafka-python -- -ra @@ -1199,7 +1199,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-kafka-python -- -ra @@ -1217,7 +1217,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-kafka-python -- -ra @@ -1235,7 +1235,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-kafka-python -- -ra @@ -1253,7 +1253,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-kafka-pythonng -- -ra @@ -1271,7 +1271,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra @@ -1289,7 +1289,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra @@ -1307,7 +1307,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra @@ -1325,7 +1325,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra @@ -1343,7 +1343,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-kafka-pythonng -- -ra @@ -1361,7 +1361,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-kafka-python -- -ra @@ -1379,7 +1379,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra @@ -1397,7 +1397,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-confluent-kafka -- -ra @@ -1415,7 +1415,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-confluent-kafka -- -ra @@ -1433,7 +1433,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-confluent-kafka -- -ra @@ -1451,7 +1451,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-confluent-kafka -- -ra @@ -1469,7 +1469,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-confluent-kafka -- -ra @@ -1487,7 +1487,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-confluent-kafka -- -ra @@ -1505,7 +1505,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-asyncio -- -ra @@ -1523,7 +1523,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-asyncio -- -ra @@ -1541,7 +1541,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-asyncio -- -ra @@ -1559,7 +1559,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-asyncio -- -ra @@ -1577,7 +1577,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-asyncio -- -ra @@ -1595,7 +1595,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-asyncio -- -ra @@ -1613,7 +1613,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-instrumentation-cassandra -- -ra @@ -1631,7 +1631,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-instrumentation-cassandra -- -ra @@ -1649,7 +1649,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-instrumentation-cassandra -- -ra @@ -1667,7 +1667,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-instrumentation-cassandra -- -ra @@ -1685,7 +1685,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-instrumentation-cassandra -- -ra @@ -1703,7 +1703,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-instrumentation-cassandra -- -ra @@ -1721,7 +1721,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-instrumentation-cassandra -- -ra @@ -1739,7 +1739,7 @@ jobs: python-version: "3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py38-test-processor-baggage -- -ra @@ -1757,7 +1757,7 @@ jobs: python-version: "3.9" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py39-test-processor-baggage -- -ra @@ -1775,7 +1775,7 @@ jobs: python-version: "3.10" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py310-test-processor-baggage -- -ra @@ -1793,7 +1793,7 @@ jobs: python-version: "3.11" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py311-test-processor-baggage -- -ra @@ -1811,7 +1811,7 @@ jobs: python-version: "3.12" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py312-test-processor-baggage -- -ra @@ -1829,7 +1829,7 @@ jobs: python-version: "3.13" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e py313-test-processor-baggage -- -ra @@ -1847,7 +1847,7 @@ jobs: python-version: "pypy-3.8" - name: Install tox - run: pip install tox + run: pip install tox-uv - name: Run tests run: tox -e pypy3-test-processor-baggage -- -ra diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8119304875..448950bccc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,6 +59,12 @@ To install `tox`, run: pip install tox ``` +You can also run tox with `uv` support. By default [tox.ini](./tox.ini) will automatically create a provisioned tox environment with `tox-uv`, but you can install it at host level: + +```sh +pip install tox-uv +``` + You can run `tox` with the following arguments: * `tox` to run all existing tox commands, including unit tests for all packages @@ -89,7 +95,7 @@ for more detail on available tox commands. ### Troubleshooting -Some packages may require additional system-wide dependencies to be installed. For example, you may need to install `libpq-dev` to run the postgresql client libraries instrumentation tests or `libsnappy-dev` to run the prometheus exporter tests. If you encounter a build error, please check the installation instructions for the package you are trying to run tests for. +Some packages may require additional system-wide dependencies to be installed. For example, you may need to install `libpq-dev` to run the postgresql client libraries instrumentation tests or `libsnappy-dev` to run the prometheus exporter tests. If you encounter a build error, please check the installation instructions for the package you are trying to run tests for. For `docs` building, you may need to install `mysql-client` and other required dependencies as necessary. Ensure the Python version used in your local setup matches the version used in the [CI](./.github/workflows/) to maintain compatibility when building the documentation. @@ -139,7 +145,7 @@ git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-python make sure you have all supported versions of Python installed, install `tox` only for the first time: ```sh -pip install tox +pip install tox tox-uv ``` Run tests in the root of the repository (this will run all tox environments and may take some time): diff --git a/tox.ini b/tox.ini index 13dd9fafb6..d198c0a836 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,6 @@ [tox] +requires = + tox-uv>=1 isolated_build = True skipsdist = True skip_missing_interpreters = True From 86a7f6bab3d394f5e9ea5c458b657373583fde21 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 17 Jan 2025 22:12:12 -0600 Subject: [PATCH 331/335] Update opentelemetry-instrumentation-openai-v2 version to v2.2b0 (#3194) --- .../opentelemetry-instrumentation-openai-v2/CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/openai_v2/version.py | 2 +- .../src/opentelemetry/instrumentation/bootstrap_gen.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index ed27904e63..0d5ed666ed 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 2.1b0 (2025-01-17) + - Coerce openai response_format to semconv format ([#3073](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3073)) - Add example to `opentelemetry-instrumentation-openai-v2` diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py index 5b77207d9d..a6098e22cc 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.1b0.dev" +__version__ = "2.2b0.dev" diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index a55f0ccd8e..071abe2ad7 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -18,7 +18,7 @@ libraries = [ { "library": "openai >= 1.26.0", - "instrumentation": "opentelemetry-instrumentation-openai-v2==2.1b0.dev", + "instrumentation": "opentelemetry-instrumentation-openai-v2==2.2b0.dev", }, { "library": "google-cloud-aiplatform >= 1.64", From 9460773e5cda6423676b8760021ed96836540f0d Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 20 Jan 2025 09:56:09 +0100 Subject: [PATCH 332/335] Basic instrumentation for Bedrock runtime Converse api (#3161) * botocore: add extension for bedrock runtime api * Add tests and handle only non streaming responses * Make it explicit we are handling only the converse operation * Simplify test since all models behaves the same * Add test for error case and rework things a bit * Add converse example * Generate workflows * Add changelog --- .github/workflows/core_contrib_test_0.yml | 28 +- .github/workflows/test_0.yml | 252 +++++++++--------- .github/workflows/test_1.yml | 216 +++++++-------- .github/workflows/test_2.yml | 108 ++++++++ CHANGELOG.md | 2 + .../examples/bedrock-runtime/zero-code/.env | 15 ++ .../bedrock-runtime/zero-code/README.rst | 50 ++++ .../bedrock-runtime/zero-code/converse.py | 22 ++ .../zero-code/requirements.txt | 6 + .../botocore/environment_variables.py | 3 + .../botocore/extensions/__init__.py | 1 + .../botocore/extensions/bedrock.py | 149 +++++++++++ ...quirements.txt => test-requirements-0.txt} | 1 + .../test-requirements-1.txt | 39 +++ .../tests/bedrock_utils.py | 116 ++++++++ .../cassettes/test_converse_with_content.yaml | 93 +++++++ .../test_converse_with_invalid_model.yaml | 69 +++++ .../tests/conftest.py | 190 +++++++++++++ .../tests/test_botocore_bedrock.py | 102 +++++++ tox.ini | 11 +- 20 files changed, 1234 insertions(+), 239 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/.env create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/converse.py create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/environment_variables.py create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py rename instrumentation/opentelemetry-instrumentation-botocore/{test-requirements.txt => test-requirements-0.txt} (97%) create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/tests/bedrock_utils.py create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_content.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_invalid_model.yaml create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/tests/conftest.py create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index 7ab737c657..bbc43ce736 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -349,8 +349,8 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-aws-lambda -- -ra - py38-test-instrumentation-botocore: - name: instrumentation-botocore + py38-test-instrumentation-botocore-0: + name: instrumentation-botocore-0 runs-on: ubuntu-latest steps: - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} @@ -369,7 +369,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py38-test-instrumentation-botocore -- -ra + run: tox -e py38-test-instrumentation-botocore-0 -- -ra + + py38-test-instrumentation-botocore-1: + name: instrumentation-botocore-1 + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-instrumentation-botocore-1 -- -ra py38-test-instrumentation-boto3sqs: name: instrumentation-boto3sqs diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index bbfb5a6865..b43a46b94f 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -1852,8 +1852,8 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - py38-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.8 Ubuntu + py38-test-instrumentation-botocore-0_ubuntu-latest: + name: instrumentation-botocore-0 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1868,10 +1868,28 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py38-test-instrumentation-botocore -- -ra + run: tox -e py38-test-instrumentation-botocore-0 -- -ra - py39-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.9 Ubuntu + py38-test-instrumentation-botocore-1_ubuntu-latest: + name: instrumentation-botocore-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-instrumentation-botocore-1 -- -ra + + py39-test-instrumentation-botocore-0_ubuntu-latest: + name: instrumentation-botocore-0 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1886,10 +1904,46 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore -- -ra + run: tox -e py39-test-instrumentation-botocore-0 -- -ra + + py39-test-instrumentation-botocore-1_ubuntu-latest: + name: instrumentation-botocore-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-1 -- -ra + + py310-test-instrumentation-botocore-0_ubuntu-latest: + name: instrumentation-botocore-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-0 -- -ra - py310-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.10 Ubuntu + py310-test-instrumentation-botocore-1_ubuntu-latest: + name: instrumentation-botocore-1 3.10 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1904,10 +1958,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-botocore -- -ra + run: tox -e py310-test-instrumentation-botocore-1 -- -ra - py311-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.11 Ubuntu + py311-test-instrumentation-botocore-0_ubuntu-latest: + name: instrumentation-botocore-0 3.11 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1922,10 +1976,28 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-botocore -- -ra + run: tox -e py311-test-instrumentation-botocore-0 -- -ra - py312-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.12 Ubuntu + py311-test-instrumentation-botocore-1_ubuntu-latest: + name: instrumentation-botocore-1 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-1 -- -ra + + py312-test-instrumentation-botocore-0_ubuntu-latest: + name: instrumentation-botocore-0 3.12 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1940,10 +2012,46 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-botocore -- -ra + run: tox -e py312-test-instrumentation-botocore-0 -- -ra + + py312-test-instrumentation-botocore-1_ubuntu-latest: + name: instrumentation-botocore-1 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-1 -- -ra + + py313-test-instrumentation-botocore-0_ubuntu-latest: + name: instrumentation-botocore-0 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-0 -- -ra - py313-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.13 Ubuntu + py313-test-instrumentation-botocore-1_ubuntu-latest: + name: instrumentation-botocore-1 3.13 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1958,7 +2066,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-botocore -- -ra + run: tox -e py313-test-instrumentation-botocore-1 -- -ra py38-test-instrumentation-boto3sqs_ubuntu-latest: name: instrumentation-boto3sqs 3.8 Ubuntu @@ -4407,111 +4515,3 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-requests -- -ra - - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra - - py310-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-requests -- -ra - - py311-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-requests -- -ra - - py312-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-requests -- -ra - - py313-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.13 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-requests -- -ra - - py38-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py38-test-instrumentation-starlette -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 7cd1b5ed61..c1712a5367 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,114 @@ env: jobs: + py39-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-requests -- -ra + + py310-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-requests -- -ra + + py311-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-requests -- -ra + + py312-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-requests -- -ra + + py313-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-requests -- -ra + + py38-test-instrumentation-starlette_ubuntu-latest: + name: instrumentation-starlette 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-instrumentation-starlette -- -ra + py39-test-instrumentation-starlette_ubuntu-latest: name: instrumentation-starlette 3.9 Ubuntu runs-on: ubuntu-latest @@ -4407,111 +4515,3 @@ jobs: - name: Run tests run: tox -e pypy3-test-util-http -- -ra - - py38-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py38-test-propagator-aws-xray-0 -- -ra - - py38-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.8 - uses: actions/setup-python@v5 - with: - python-version: "3.8" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py38-test-propagator-aws-xray-1 -- -ra - - py39-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra - - py39-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra - - py310-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-aws-xray-0 -- -ra - - py310-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-aws-xray-1 -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index fd1dcb00e0..bc52c4eba4 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -16,6 +16,114 @@ env: jobs: + py38-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-propagator-aws-xray-0 -- -ra + + py38-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-propagator-aws-xray-1 -- -ra + + py39-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-0 -- -ra + + py39-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-1 -- -ra + + py310-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-0 -- -ra + + py310-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-1 -- -ra + py311-test-propagator-aws-xray-0_ubuntu-latest: name: propagator-aws-xray-0 3.11 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e40e73270..39e3fcdba8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3129](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3129)) - `opentelemetry-util-http` Add `py.typed` file to enable PEP 561 ([#3127](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3127)) +- `opentelemetry-opentelemetry-botocore` Add basic support for GenAI attributes for AWS Bedrock Converse API + ([#3161](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3161)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/.env b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/.env new file mode 100644 index 0000000000..0ab6418c72 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/.env @@ -0,0 +1,15 @@ +# Update this with your real values +AWS_ACCESS_KEY_ID=key +AWS_SECRET_ACCESS_KEY=secret +AWS_DEFAULT_REGION=eu-central-1 +# Uncomment and set if your credentials are temporary +# AWS_SESSION_TOKEN= + +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + +OTEL_SERVICE_NAME=opentelemetry-python-bedrock + +# Uncomment if your OTLP endpoint doesn't support logs +# OTEL_LOGS_EXPORTER=console diff --git a/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/README.rst b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/README.rst new file mode 100644 index 0000000000..37e1db9b30 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/README.rst @@ -0,0 +1,50 @@ +Bedrock Zero-Code Instrumentation Example +========================================= + +This is an example of how to instrument Bedrock calls with zero code changes, +using `opentelemetry-instrument`. + +When examples are run, it exports traces and logs to an OTLP +compatible endpoint. Traces include details such as the model used and the +duration of the chat request. Logs capture the chat request and the generated +response, providing a comprehensive view of the performance and behavior of +your OpenAI requests. + +Note: `.env <.env>`_ file configures additional environment variables: + +- `OTEL_LOGS_EXPORTER=otlp` to specify exporter type. + +Available examples +------------------ + +- `converse.py` uses `bedrock-runtime` `Converse API _`. + +Setup +----- + +Minimally, update the `.env <.env>`_ file with your "AWS_SECRET_ACCESS_KEY", +"AWS_SECRET_ACCESS_KEY", "AWS_DEFAULT_REGION" and if you are using temporary +credentials "AWS_SESSION_TOKEN". An +OTLP compatible endpoint should be listening for traces and logs on +http://localhost:4317. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example like this: + +:: + + dotenv run -- opentelemetry-instrument python converse.py + +You should see a poem generated by Bedrock while traces exported to your +configured observability tool. diff --git a/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/converse.py b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/converse.py new file mode 100644 index 0000000000..b6ce55d50d --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/converse.py @@ -0,0 +1,22 @@ +import os + +import boto3 + + +def main(): + client = boto3.client("bedrock-runtime") + response = client.converse( + modelId=os.getenv("CHAT_MODEL", "amazon.titan-text-lite-v1"), + messages=[ + { + "role": "user", + "content": [{"text": "Write a short poem on OpenTelemetry."}], + }, + ], + ) + + print(response["output"]["message"]["content"][0]["text"]) + + +if __name__ == "__main__": + main() diff --git a/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/requirements.txt new file mode 100644 index 0000000000..dea6c40109 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/examples/bedrock-runtime/zero-code/requirements.txt @@ -0,0 +1,6 @@ +boto3~=1.35.99 + +opentelemetry-sdk~=1.29.0 +opentelemetry-exporter-otlp-proto-grpc~=1.29.0 +opentelemetry-distro~=0.50b0 +opentelemetry-instrumentation-botocore~=0.50b0 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/environment_variables.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/environment_variables.py new file mode 100644 index 0000000000..02bdfe68af --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/environment_variables.py @@ -0,0 +1,3 @@ +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = ( + "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" +) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py index 85a4904022..c4624ababd 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py @@ -32,6 +32,7 @@ def loader(): _KNOWN_EXTENSIONS = { + "bedrock-runtime": _lazy_load(".bedrock", "_BedrockRuntimeExtension"), "dynamodb": _lazy_load(".dynamodb", "_DynamoDbExtension"), "lambda": _lazy_load(".lmbd", "_LambdaExtension"), "sns": _lazy_load(".sns", "_SnsExtension"), diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py new file mode 100644 index 0000000000..fe826da603 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py @@ -0,0 +1,149 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Includes work from: +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +from typing import Any + +from opentelemetry.instrumentation.botocore.extensions.types import ( + _AttributeMapT, + _AwsSdkExtension, + _BotoClientErrorT, +) +from opentelemetry.semconv._incubating.attributes.error_attributes import ( + ERROR_TYPE, +) +from opentelemetry.semconv._incubating.attributes.gen_ai_attributes import ( + GEN_AI_OPERATION_NAME, + GEN_AI_REQUEST_MAX_TOKENS, + GEN_AI_REQUEST_MODEL, + GEN_AI_REQUEST_STOP_SEQUENCES, + GEN_AI_REQUEST_TEMPERATURE, + GEN_AI_REQUEST_TOP_P, + GEN_AI_RESPONSE_FINISH_REASONS, + GEN_AI_SYSTEM, + GEN_AI_USAGE_INPUT_TOKENS, + GEN_AI_USAGE_OUTPUT_TOKENS, + GenAiOperationNameValues, + GenAiSystemValues, +) +from opentelemetry.trace.span import Span +from opentelemetry.trace.status import Status, StatusCode + +_logger = logging.getLogger(__name__) + +_MODEL_ID_KEY: str = "modelId" + + +class _BedrockRuntimeExtension(_AwsSdkExtension): + """ + This class is an extension for + Amazon Bedrock Runtime. + """ + + _HANDLED_OPERATIONS = {"Converse"} + + def extract_attributes(self, attributes: _AttributeMapT): + if self._call_context.operation not in self._HANDLED_OPERATIONS: + return + + attributes[GEN_AI_SYSTEM] = GenAiSystemValues.AWS_BEDROCK.value + + model_id = self._call_context.params.get(_MODEL_ID_KEY) + if model_id: + attributes[GEN_AI_REQUEST_MODEL] = model_id + attributes[GEN_AI_OPERATION_NAME] = ( + GenAiOperationNameValues.CHAT.value + ) + + if inference_config := self._call_context.params.get( + "inferenceConfig" + ): + self._set_if_not_none( + attributes, + GEN_AI_REQUEST_TEMPERATURE, + inference_config.get("temperature"), + ) + self._set_if_not_none( + attributes, + GEN_AI_REQUEST_TOP_P, + inference_config.get("topP"), + ) + self._set_if_not_none( + attributes, + GEN_AI_REQUEST_MAX_TOKENS, + inference_config.get("maxTokens"), + ) + self._set_if_not_none( + attributes, + GEN_AI_REQUEST_STOP_SEQUENCES, + inference_config.get("stopSequences"), + ) + + @staticmethod + def _set_if_not_none(attributes, key, value): + if value is not None: + attributes[key] = value + + def before_service_call(self, span: Span): + if self._call_context.operation not in self._HANDLED_OPERATIONS: + return + + if not span.is_recording(): + return + + operation_name = span.attributes.get(GEN_AI_OPERATION_NAME, "") + request_model = span.attributes.get(GEN_AI_REQUEST_MODEL, "") + # avoid setting to an empty string if are not available + if operation_name and request_model: + span.update_name(f"{operation_name} {request_model}") + + def on_success(self, span: Span, result: dict[str, Any]): + if self._call_context.operation not in self._HANDLED_OPERATIONS: + return + + if not span.is_recording(): + return + + if usage := result.get("usage"): + if input_tokens := usage.get("inputTokens"): + span.set_attribute( + GEN_AI_USAGE_INPUT_TOKENS, + input_tokens, + ) + if output_tokens := usage.get("outputTokens"): + span.set_attribute( + GEN_AI_USAGE_OUTPUT_TOKENS, + output_tokens, + ) + + if stop_reason := result.get("stopReason"): + span.set_attribute( + GEN_AI_RESPONSE_FINISH_REASONS, + [stop_reason], + ) + + def on_error(self, span: Span, exception: _BotoClientErrorT): + if self._call_context.operation not in self._HANDLED_OPERATIONS: + return + + span.set_status(Status(StatusCode.ERROR, str(exception))) + if span.is_recording(): + span.set_attribute(ERROR_TYPE, type(exception).__qualname__) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt similarity index 97% rename from instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt rename to instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt index aa5f89859f..ee28a1f2ba 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt @@ -19,6 +19,7 @@ pluggy==1.5.0 py-cpuinfo==9.0.0 pycparser==2.21 pytest==7.4.4 +pytest-vcr==1.0.2 python-dateutil==2.8.2 pytz==2024.1 PyYAML==6.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt new file mode 100644 index 0000000000..c4695ff27c --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt @@ -0,0 +1,39 @@ +asgiref==3.8.1 +aws-xray-sdk==2.12.1 +boto3==1.35.56 +botocore==1.35.56 +certifi==2024.7.4 +cffi==1.17.0 +charset-normalizer==3.3.2 +cryptography==43.0.1 +Deprecated==1.2.14 +docker==7.0.0 +idna==3.7 +iniconfig==2.0.0 +Jinja2==3.1.4 +jmespath==1.0.1 +MarkupSafe==2.1.5 +moto==5.0.9 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pycparser==2.21 +pytest==7.4.4 +pytest-vcr==1.0.2 +python-dateutil==2.8.2 +pytz==2024.1 +PyYAML==6.0.1 +requests==2.32.3 +responses==0.25.0 +s3transfer==0.10.0 +six==1.16.0 +tomli==2.0.1 +typing_extensions==4.12.2 +urllib3==1.26.19 +Werkzeug==3.0.6 +wrapt==1.16.0 +xmltodict==0.13.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e propagator/opentelemetry-propagator-aws-xray +-e instrumentation/opentelemetry-instrumentation-botocore diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/bedrock_utils.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/bedrock_utils.py new file mode 100644 index 0000000000..6d2415432f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/bedrock_utils.py @@ -0,0 +1,116 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +from typing import Any + +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) + + +def assert_completion_attributes( + span: ReadableSpan, + request_model: str, + response: dict[str, Any] | None, + operation_name: str = "chat", + request_top_p: int | None = None, + request_temperature: int | None = None, + request_max_tokens: int | None = None, + request_stop_sequences: list[str] | None = None, +): + if usage := (response and response.get("usage")): + input_tokens = usage["inputTokens"] + output_tokens = usage["outputTokens"] + else: + input_tokens, output_tokens = None, None + + if response: + finish_reason = (response["stopReason"],) + else: + finish_reason = None + + return assert_all_attributes( + span, + request_model, + input_tokens, + output_tokens, + finish_reason, + operation_name, + request_top_p, + request_temperature, + request_max_tokens, + tuple(request_stop_sequences) + if request_stop_sequences is not None + else request_stop_sequences, + ) + + +def assert_equal_or_not_present(value, attribute_name, span): + if value: + assert value == span.attributes[attribute_name] + else: + assert attribute_name not in span.attributes + + +def assert_all_attributes( + span: ReadableSpan, + request_model: str, + input_tokens: int | None = None, + output_tokens: int | None = None, + finish_reason: tuple[str] | None = None, + operation_name: str = "chat", + request_top_p: int | None = None, + request_temperature: int | None = None, + request_max_tokens: int | None = None, + request_stop_sequences: tuple[str] | None = None, +): + assert span.name == f"{operation_name} {request_model}" + assert ( + operation_name + == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + ) + assert ( + GenAIAttributes.GenAiSystemValues.AWS_BEDROCK.value + == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] + ) + assert ( + request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + ) + + assert_equal_or_not_present( + input_tokens, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, span + ) + assert_equal_or_not_present( + output_tokens, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, span + ) + assert_equal_or_not_present( + finish_reason, GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, span + ) + assert_equal_or_not_present( + request_top_p, GenAIAttributes.GEN_AI_REQUEST_TOP_P, span + ) + assert_equal_or_not_present( + request_temperature, GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE, span + ) + assert_equal_or_not_present( + request_max_tokens, GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS, span + ) + assert_equal_or_not_present( + request_stop_sequences, + GenAIAttributes.GEN_AI_REQUEST_STOP_SEQUENCES, + span, + ) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_content.yaml b/instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_content.yaml new file mode 100644 index 0000000000..8060f02076 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_content.yaml @@ -0,0 +1,93 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": [ + { + "text": "Say this is a test" + } + ] + } + ], + "inferenceConfig": { + "maxTokens": 10, + "temperature": 0.8, + "topP": 1, + "stopSequences": [ + "|" + ] + } + } + headers: + Content-Length: + - '170' + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + User-Agent: + - !!binary | + Qm90bzMvMS4zNS41NiBtZC9Cb3RvY29yZSMxLjM1LjU2IHVhLzIuMCBvcy9saW51eCM2LjEuMC0x + MDM0LW9lbSBtZC9hcmNoI3g4Nl82NCBsYW5nL3B5dGhvbiMzLjEwLjEyIG1kL3B5aW1wbCNDUHl0 + aG9uIGNmZy9yZXRyeS1tb2RlI2xlZ2FjeSBCb3RvY29yZS8xLjM1LjU2 + X-Amz-Date: + - !!binary | + MjAyNDEyMzFUMTMyMDQxWg== + X-Amz-Security-Token: + - test_aws_security_token + X-Amzn-Trace-Id: + - !!binary | + Um9vdD0xLWY1MWY4NGM1LTNiZjk4YzY0YWMyNmJhNTk1OWJjODgxNjtQYXJlbnQ9YjNmOGZhM2Mz + MDc1NGEzZjtTYW1wbGVkPTE= + amz-sdk-invocation-id: + - !!binary | + OTIyMjczMzItY2I5ZS00NGM1LTliZGUtYjU0NmJmODkxYmEy + amz-sdk-request: + - !!binary | + YXR0ZW1wdD0x + authorization: + - Bearer test_aws_authorization + method: POST + uri: https://bedrock-runtime.eu-central-1.amazonaws.com/model/amazon.titan-text-lite-v1/converse + response: + body: + string: |- + { + "metrics": { + "latencyMs": 811 + }, + "output": { + "message": { + "content": [ + { + "text": "I am happy to assist you today" + } + ], + "role": "assistant" + } + }, + "stopReason": "max_tokens", + "usage": { + "inputTokens": 8, + "outputTokens": 10, + "totalTokens": 18 + } + } + headers: + Connection: + - keep-alive + Content-Length: + - '212' + Content-Type: + - application/json + Date: + - Tue, 31 Dec 2024 13:20:42 GMT + Set-Cookie: test_set_cookie + x-amzn-RequestId: + - 63dfbcb2-3536-4906-b10d-e5b126b3c0ae + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_invalid_model.yaml b/instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_invalid_model.yaml new file mode 100644 index 0000000000..ecbfb6bbd0 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/cassettes/test_converse_with_invalid_model.yaml @@ -0,0 +1,69 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": [ + { + "text": "Say this is a test" + } + ] + } + ] + } + headers: + Content-Length: + - '77' + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + User-Agent: + - !!binary | + Qm90bzMvMS4zNS41NiBtZC9Cb3RvY29yZSMxLjM1LjU2IHVhLzIuMCBvcy9saW51eCM2LjEuMC0x + MDM0LW9lbSBtZC9hcmNoI3g4Nl82NCBsYW5nL3B5dGhvbiMzLjEwLjEyIG1kL3B5aW1wbCNDUHl0 + aG9uIGNmZy9yZXRyeS1tb2RlI2xlZ2FjeSBCb3RvY29yZS8xLjM1LjU2 + X-Amz-Date: + - !!binary | + MjAyNTAxMTVUMTEwMTQ3Wg== + X-Amz-Security-Token: + - test_aws_security_token + X-Amzn-Trace-Id: + - !!binary | + Um9vdD0xLWIzM2JhNTkxLTdkYmQ0ZDZmYTBmZTdmYzc2MTExOThmNztQYXJlbnQ9NzRmNmQ1NTEz + MzkzMzUxNTtTYW1wbGVkPTE= + amz-sdk-invocation-id: + - !!binary | + NTQ5MmQ0NTktNzhkNi00ZWY4LTlmMDMtZTA5ODhkZGRiZDI5 + amz-sdk-request: + - !!binary | + YXR0ZW1wdD0x + authorization: + - Bearer test_aws_authorization + method: POST + uri: https://bedrock-runtime.eu-central-1.amazonaws.com/model/does-not-exist/converse + response: + body: + string: |- + { + "message": "The provided model identifier is invalid." + } + headers: + Connection: + - keep-alive + Content-Length: + - '55' + Content-Type: + - application/json + Date: + - Wed, 15 Jan 2025 11:01:47 GMT + Set-Cookie: test_set_cookie + x-amzn-ErrorType: + - ValidationException:http://internal.amazon.com/coral/com.amazon.bedrock/ + x-amzn-RequestId: + - d425bf99-8a4e-4d83-8d77-a48410dd82b2 + status: + code: 400 + message: Bad Request +version: 1 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/conftest.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/conftest.py new file mode 100644 index 0000000000..271c540da7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/conftest.py @@ -0,0 +1,190 @@ +"""Unit tests configuration module.""" + +import json +import os + +import boto3 +import pytest +import yaml + +from opentelemetry.instrumentation.botocore import BotocoreInstrumentor +from opentelemetry.instrumentation.botocore.environment_variables import ( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, +) +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, + SimpleLogRecordProcessor, +) +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + + +@pytest.fixture(scope="function", name="span_exporter") +def fixture_span_exporter(): + exporter = InMemorySpanExporter() + yield exporter + + +@pytest.fixture(scope="function", name="log_exporter") +def fixture_log_exporter(): + exporter = InMemoryLogExporter() + yield exporter + + +@pytest.fixture(scope="function", name="tracer_provider") +def fixture_tracer_provider(span_exporter): + provider = TracerProvider() + provider.add_span_processor(SimpleSpanProcessor(span_exporter)) + return provider + + +@pytest.fixture(scope="function", name="event_logger_provider") +def fixture_event_logger_provider(log_exporter): + provider = LoggerProvider() + provider.add_log_record_processor(SimpleLogRecordProcessor(log_exporter)) + event_logger_provider = EventLoggerProvider(provider) + + return event_logger_provider + + +@pytest.fixture +def bedrock_runtime_client(): + return boto3.client("bedrock-runtime") + + +@pytest.fixture(autouse=True) +def environment(): + if not os.getenv("AWS_ACCESS_KEY_ID"): + os.environ["AWS_ACCESS_KEY_ID"] = "test_aws_access_key_id" + if not os.getenv("AWS_SECRET_ACCESS_KEY"): + os.environ["AWS_SECRET_ACCESS_KEY"] = "test_aws_secret_key" + if not os.getenv("AWS_SESSION_TOKEN"): + os.environ["AWS_SESSION_TOKEN"] = "test_aws_session_token" + if not os.getenv("AWS_DEFAULT_REGION"): + os.environ["AWS_DEFAULT_REGION"] = "eu-central-1" + + +@pytest.fixture(scope="module") +def vcr_config(): + return { + "filter_headers": [ + ("cookie", "test_cookie"), + ("authorization", "Bearer test_aws_authorization"), + ("X-Amz-Security-Token", "test_aws_security_token"), + ], + "decode_compressed_response": True, + "before_record_response": scrub_response_headers, + } + + +@pytest.fixture(scope="function") +def instrument_no_content(tracer_provider, event_logger_provider): + os.environ.update( + {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"} + ) + + instrumentor = BotocoreInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + event_logger_provider=event_logger_provider, + ) + + yield instrumentor + os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) + instrumentor.uninstrument() + + +@pytest.fixture(scope="function") +def instrument_with_content(tracer_provider, event_logger_provider): + os.environ.update( + {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} + ) + instrumentor = BotocoreInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + event_logger_provider=event_logger_provider, + ) + + yield instrumentor + os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) + instrumentor.uninstrument() + + +class LiteralBlockScalar(str): + """Formats the string as a literal block scalar, preserving whitespace and + without interpreting escape characters""" + + +def literal_block_scalar_presenter(dumper, data): + """Represents a scalar string as a literal block, via '|' syntax""" + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|") + + +yaml.add_representer(LiteralBlockScalar, literal_block_scalar_presenter) + + +def process_string_value(string_value): + """Pretty-prints JSON or returns long strings as a LiteralBlockScalar""" + try: + json_data = json.loads(string_value) + return LiteralBlockScalar(json.dumps(json_data, indent=2)) + except (ValueError, TypeError): + if len(string_value) > 80: + return LiteralBlockScalar(string_value) + return string_value + + +def convert_body_to_literal(data): + """Searches the data for body strings, attempting to pretty-print JSON""" + if isinstance(data, dict): + for key, value in data.items(): + # Handle response body case (e.g., response.body.string) + if key == "body" and isinstance(value, dict) and "string" in value: + value["string"] = process_string_value(value["string"]) + + # Handle request body case (e.g., request.body) + elif key == "body" and isinstance(value, str): + data[key] = process_string_value(value) + + else: + convert_body_to_literal(value) + + elif isinstance(data, list): + for idx, choice in enumerate(data): + data[idx] = convert_body_to_literal(choice) + + return data + + +class PrettyPrintJSONBody: + """This makes request and response body recordings more readable.""" + + @staticmethod + def serialize(cassette_dict): + cassette_dict = convert_body_to_literal(cassette_dict) + return yaml.dump( + cassette_dict, default_flow_style=False, allow_unicode=True + ) + + @staticmethod + def deserialize(cassette_string): + return yaml.load(cassette_string, Loader=yaml.Loader) + + +@pytest.fixture(scope="module", autouse=True) +def fixture_vcr(vcr): + vcr.register_serializer("yaml", PrettyPrintJSONBody) + return vcr + + +def scrub_response_headers(response): + """ + This scrubs sensitive response headers. Note they are case-sensitive! + """ + response["headers"]["Set-Cookie"] = "test_set_cookie" + return response diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py new file mode 100644 index 0000000000..8de7721bc9 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py @@ -0,0 +1,102 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +import boto3 +import pytest + +from opentelemetry.semconv._incubating.attributes.error_attributes import ( + ERROR_TYPE, +) +from opentelemetry.trace.status import StatusCode + +from .bedrock_utils import assert_completion_attributes + +BOTO3_VERSION = tuple(int(x) for x in boto3.__version__.split(".")) + + +@pytest.mark.skipif( + BOTO3_VERSION < (1, 35, 56), reason="Converse API not available" +) +@pytest.mark.vcr() +def test_converse_with_content( + span_exporter, + log_exporter, + bedrock_runtime_client, + instrument_with_content, +): + messages = [{"role": "user", "content": [{"text": "Say this is a test"}]}] + + llm_model_value = "amazon.titan-text-lite-v1" + max_tokens, temperature, top_p, stop_sequences = 10, 0.8, 1, ["|"] + response = bedrock_runtime_client.converse( + messages=messages, + modelId=llm_model_value, + inferenceConfig={ + "maxTokens": max_tokens, + "temperature": temperature, + "topP": top_p, + "stopSequences": stop_sequences, + }, + ) + + (span,) = span_exporter.get_finished_spans() + assert_completion_attributes( + span, + llm_model_value, + response, + "chat", + top_p, + temperature, + max_tokens, + stop_sequences, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 0 + + +@pytest.mark.skipif( + BOTO3_VERSION < (1, 35, 56), reason="Converse API not available" +) +@pytest.mark.vcr() +def test_converse_with_invalid_model( + span_exporter, + log_exporter, + bedrock_runtime_client, + instrument_with_content, +): + messages = [{"role": "user", "content": [{"text": "Say this is a test"}]}] + + llm_model_value = "does-not-exist" + with pytest.raises(bedrock_runtime_client.exceptions.ValidationException): + bedrock_runtime_client.converse( + messages=messages, + modelId=llm_model_value, + ) + + (span,) = span_exporter.get_finished_spans() + assert_completion_attributes( + span, + llm_model_value, + None, + "chat", + ) + + assert span.status.status_code == StatusCode.ERROR + assert span.attributes[ERROR_TYPE] == "ValidationException" + + logs = log_exporter.get_finished_logs() + assert len(logs) == 0 diff --git a/tox.ini b/tox.ini index d198c0a836..70c6ae6a28 100644 --- a/tox.ini +++ b/tox.ini @@ -66,7 +66,7 @@ envlist = lint-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{8,9,10,11,12,13}-test-instrumentation-botocore + py3{8,9,10,11,12,13}-test-instrumentation-botocore-{0,1} ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore @@ -414,6 +414,11 @@ test_deps = opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils +pass_env = + AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY + AWS_SESSION_TOKEN + AWS_DEFAULT_REGION deps = lint: -r dev-requirements.txt @@ -518,7 +523,9 @@ deps = lint-instrumentation-urllib3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt botocore: {[testenv]test_deps} - botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements.txt + botocore-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt + botocore-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt + lint-instrumentation-botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt cassandra: {[testenv]test_deps} cassandra: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt From 20413ef7d72a3064492a9374e5164214949e60b9 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 21 Jan 2025 02:10:48 -0600 Subject: [PATCH 333/335] Copy changelog updates from package-release/opentelemetry-instrumentation-openai-v2/v2.1bx (#3197) Co-authored-by: Riccardo Magliocchetti --- .../opentelemetry-instrumentation-openai-v2/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 0d5ed666ed..91065edbc1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -## Version 2.1b0 (2025-01-17) +## Version 2.1b0 (2025-01-18) - Coerce openai response_format to semconv format ([#3073](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3073)) From 37f85bf8cc235b807557c8a1aff9fa3b52b3d111 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 21 Jan 2025 14:57:53 +0100 Subject: [PATCH 334/335] instrumentation/aws-lambda: don't print warnings outside of AWS Lambda (#3183) If we are not running inside AWS Lambda don't print warnings on missing OTel lambda extension layer. The instrumentation is installed by the OTel k8s operator and so this warning may confuse users. --- .../instrumentation/aws_lambda/__init__.py | 5 +++ .../test_aws_lambda_instrumentation_manual.py | 38 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index b1f61b9ce8..a0d381e7f5 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -431,6 +431,11 @@ def _instrument(self, **kwargs): the context is extracted from the HTTP headers of an API Gateway request. """ + + # Don't try if we are not running on AWS Lambda + if "AWS_LAMBDA_FUNCTION_NAME" not in os.environ: + return + lambda_handler = os.environ.get(ORIG_HANDLER, os.environ.get(_HANDLER)) if not lambda_handler: logger.warning( diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index 4ac1e9c873..1e8f9f0575 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -11,6 +11,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +import logging import os from dataclasses import dataclass from importlib import import_module, reload @@ -124,7 +126,10 @@ def setUp(self): super().setUp() self.common_env_patch = mock.patch.dict( "os.environ", - {_HANDLER: "tests.mocks.lambda_function.handler"}, + { + _HANDLER: "tests.mocks.lambda_function.handler", + "AWS_LAMBDA_FUNCTION_NAME": "mylambda", + }, ) self.common_env_patch.start() @@ -466,12 +471,14 @@ def test_lambda_handles_handler_exception(self): exc_env_patch.stop() - def test_lambda_handles_should_do_nothing_when_environment_variables_not_present( - self, + @mock.patch("opentelemetry.instrumentation.aws_lambda.logger") + def test_lambda_handles_should_do_nothing_when_aws_lambda_environment_variables_not_present( + self, logger_mock ): exc_env_patch = mock.patch.dict( "os.environ", - {_HANDLER: ""}, + {_HANDLER: "tests.mocks.lambda_function.handler"}, + clear=True, ) exc_env_patch.start() AwsLambdaInstrumentor().instrument() @@ -480,6 +487,29 @@ def test_lambda_handles_should_do_nothing_when_environment_variables_not_present self.assertEqual(len(spans), 0) exc_env_patch.stop() + logger_mock.warnings.assert_not_called() + + def test_lambda_handles_should_warn_when_handler_environment_variable_not_present( + self, + ): + exc_env_patch = mock.patch.dict( + "os.environ", + {"AWS_LAMBDA_FUNCTION_NAME": "mylambda"}, + clear=True, + ) + exc_env_patch.start() + with self.assertLogs(level=logging.WARNING) as warning: + AwsLambdaInstrumentor().instrument() + self.assertEqual(len(warning.records), 1) + self.assertIn( + "This instrumentation requires the OpenTelemetry Lambda extension installed", + warning.records[0].message, + ) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + exc_env_patch.stop() + def test_uninstrument(self): AwsLambdaInstrumentor().instrument() From 3f50c08580f97519d7053bc399605edf8de9a6dd Mon Sep 17 00:00:00 2001 From: Josh Owen Date: Tue, 21 Jan 2025 15:41:56 -0500 Subject: [PATCH 335/335] psycopg2-binary support (#3186) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * psycopg2-binary support * changelog * Update CHANGELOG.md * Update pyproject.toml * fix * lint * added test config * Update bootstrap_gen.py * update tox * Update tox.ini * regenerate workflows * workflows --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/workflows/core_contrib_test_0.yml | 22 ++ .github/workflows/test_1.yml | 216 +++++++++--------- .github/workflows/test_2.yml | 108 +++++++++ CHANGELOG.md | 2 + instrumentation/README.md | 2 +- .../pyproject.toml | 1 + .../instrumentation/psycopg2/__init__.py | 22 +- .../instrumentation/psycopg2/package.py | 8 +- .../test-requirements-binary.txt | 15 ++ .../instrumentation/bootstrap_gen.py | 4 + tox.ini | 7 + 11 files changed, 296 insertions(+), 111 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index bbc43ce736..6a70ce8380 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -1075,6 +1075,28 @@ jobs: - name: Run tests run: tox -e py38-test-instrumentation-psycopg2 -- -ra + py38-test-instrumentation-psycopg2-binary: + name: instrumentation-psycopg2-binary + runs-on: ubuntu-latest + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg2-binary -- -ra + py38-test-instrumentation-psycopg: name: instrumentation-psycopg runs-on: ubuntu-latest diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index c1712a5367..b27fe28466 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -1222,6 +1222,114 @@ jobs: - name: Run tests run: tox -e py313-test-instrumentation-psycopg2 -- -ra + py38-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.8 + uses: actions/setup-python@v5 + with: + python-version: "3.8" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py38-test-instrumentation-psycopg2-binary -- -ra + + py39-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra + + py310-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra + + py311-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg2-binary -- -ra + + py312-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg2-binary -- -ra + + py313-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-psycopg2-binary -- -ra + py38-test-instrumentation-psycopg_ubuntu-latest: name: instrumentation-psycopg 3.8 Ubuntu runs-on: ubuntu-latest @@ -4407,111 +4515,3 @@ jobs: - name: Run tests run: tox -e py38-test-util-http -- -ra - - py39-test-util-http_ubuntu-latest: - name: util-http 3.9 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-http -- -ra - - py310-test-util-http_ubuntu-latest: - name: util-http 3.10 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-util-http -- -ra - - py311-test-util-http_ubuntu-latest: - name: util-http 3.11 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-util-http -- -ra - - py312-test-util-http_ubuntu-latest: - name: util-http 3.12 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-util-http -- -ra - - py313-test-util-http_ubuntu-latest: - name: util-http 3.13 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-util-http -- -ra - - pypy3-test-util-http_ubuntu-latest: - name: util-http pypy-3.8 Ubuntu - runs-on: ubuntu-latest - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.8 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.8" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-util-http -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index bc52c4eba4..d9b622c5c3 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -16,6 +16,114 @@ env: jobs: + py39-test-util-http_ubuntu-latest: + name: util-http 3.9 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-util-http -- -ra + + py310-test-util-http_ubuntu-latest: + name: util-http 3.10 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-util-http -- -ra + + py311-test-util-http_ubuntu-latest: + name: util-http 3.11 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-util-http -- -ra + + py312-test-util-http_ubuntu-latest: + name: util-http 3.12 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-util-http -- -ra + + py313-test-util-http_ubuntu-latest: + name: util-http 3.13 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-util-http -- -ra + + pypy3-test-util-http_ubuntu-latest: + name: util-http pypy-3.8 Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.8 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.8" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-util-http -- -ra + py38-test-propagator-aws-xray-0_ubuntu-latest: name: propagator-aws-xray-0 3.8 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 39e3fcdba8..3838bd844f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3129](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3129)) - `opentelemetry-util-http` Add `py.typed` file to enable PEP 561 ([#3127](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3127)) +- `opentelemetry-instrumentation-psycopg2` Add support for psycopg2-binary + ([#3186](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3186)) - `opentelemetry-opentelemetry-botocore` Add basic support for GenAI attributes for AWS Bedrock Converse API ([#3161](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3161)) diff --git a/instrumentation/README.md b/instrumentation/README.md index 75341dad9a..a229951b4b 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -32,7 +32,7 @@ | [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | experimental | [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 | No | experimental | [opentelemetry-instrumentation-psycopg](./opentelemetry-instrumentation-psycopg) | psycopg >= 3.1.0 | No | experimental -| [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1 | No | experimental +| [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1,psycopg2-binary >= 2.7.3.1 | No | experimental | [opentelemetry-instrumentation-pymemcache](./opentelemetry-instrumentation-pymemcache) | pymemcache >= 1.3.5, < 5 | No | experimental | [opentelemetry-instrumentation-pymongo](./opentelemetry-instrumentation-pymongo) | pymongo >= 3.1, < 5.0 | No | experimental | [opentelemetry-instrumentation-pymysql](./opentelemetry-instrumentation-pymysql) | PyMySQL < 2 | No | experimental diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index c8ce3e8dfa..54f5bf6f3e 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -34,6 +34,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ "psycopg2 >= 2.7.3.1", + "psycopg2-binary >= 2.7.3.1", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py index f03ad1de0d..022c59f031 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py @@ -139,6 +139,7 @@ import logging import typing +from importlib.metadata import PackageNotFoundError, distribution from typing import Collection import psycopg2 @@ -149,7 +150,11 @@ from opentelemetry.instrumentation import dbapi from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.psycopg2.package import _instruments +from opentelemetry.instrumentation.psycopg2.package import ( + _instruments, + _instruments_psycopg2, + _instruments_psycopg2_binary, +) from opentelemetry.instrumentation.psycopg2.version import __version__ _logger = logging.getLogger(__name__) @@ -167,6 +172,21 @@ class Psycopg2Instrumentor(BaseInstrumentor): _DATABASE_SYSTEM = "postgresql" def instrumentation_dependencies(self) -> Collection[str]: + # Determine which package of psycopg2 is installed + # Right now there are two packages, psycopg2 and psycopg2-binary + # The latter is a binary wheel package that does not require a compiler + try: + distribution("psycopg2") + return (_instruments_psycopg2,) + except PackageNotFoundError: + pass + + try: + distribution("psycopg2-binary") + return (_instruments_psycopg2_binary,) + except PackageNotFoundError: + pass + return _instruments def _instrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/package.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/package.py index 9757a8df79..b1bf92901a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/package.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/package.py @@ -13,4 +13,10 @@ # limitations under the License. -_instruments = ("psycopg2 >= 2.7.3.1",) +_instruments_psycopg2 = "psycopg2 >= 2.7.3.1" +_instruments_psycopg2_binary = "psycopg2-binary >= 2.7.3.1" + +_instruments = ( + _instruments_psycopg2, + _instruments_psycopg2_binary, +) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt new file mode 100644 index 0000000000..80fa036b99 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt @@ -0,0 +1,15 @@ +asgiref==3.8.1 +Deprecated==1.2.14 +iniconfig==2.0.0 +packaging==24.0 +pluggy==1.5.0 +psycopg2-binary==2.9.10 +py-cpuinfo==9.0.0 +pytest==7.4.4 +tomli==2.0.1 +typing_extensions==4.12.2 +wrapt==1.16.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e instrumentation/opentelemetry-instrumentation-dbapi +-e instrumentation/opentelemetry-instrumentation-psycopg2 diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 071abe2ad7..cea9e3e11f 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -144,6 +144,10 @@ "library": "psycopg2 >= 2.7.3.1", "instrumentation": "opentelemetry-instrumentation-psycopg2==0.51b0.dev", }, + { + "library": "psycopg2-binary >= 2.7.3.1", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.51b0.dev", + }, { "library": "pymemcache >= 1.3.5, < 5", "instrumentation": "opentelemetry-instrumentation-pymemcache==0.51b0.dev", diff --git a/tox.ini b/tox.ini index 70c6ae6a28..806c74b426 100644 --- a/tox.ini +++ b/tox.ini @@ -212,6 +212,7 @@ envlist = ; opentelemetry-instrumentation-psycopg2 py3{8,9,10,11,12,13}-test-instrumentation-psycopg2 + py3{8,9,10,11,12,13}-test-instrumentation-psycopg2-binary ; ext-psycopg2 intentionally excluded from pypy3 lint-instrumentation-psycopg2 @@ -574,6 +575,9 @@ deps = psycopg2: {[testenv]test_deps} psycopg2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt + psycopg2-binary: {[testenv]test_deps} + psycopg2-binary: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt + pymysql: {[testenv]test_deps} pymysql: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -813,6 +817,9 @@ commands = test-instrumentation-psycopg2: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/tests {posargs} lint-instrumentation-psycopg2: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-psycopg2" + ; Test only for psycopg2-binary instrumentation as the only difference between psycopg2 and psycopg2-binary is the install method + test-instrumentation-psycopg2-binary: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg2/tests {posargs} + test-instrumentation-pymemcache: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache/tests {posargs} lint-instrumentation-pymemcache: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-pymemcache"