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/component_owners.yml b/.github/component_owners.yml index dcc1013476..3aeb90b297 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -66,3 +66,10 @@ components: processor/opentelemetry-processor-baggage: - codeboten + + instrumentation-genai/: + - karthikscale3 + - lmolkova + - lzchen + - gyliu513 + - nirga 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/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..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 @@ -46,13 +50,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/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/misc_0.yml b/.github/workflows/misc_0.yml index 3c3f7bfacf..ca94a69563 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -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 @@ -122,8 +124,31 @@ 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 - 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/.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/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index d251737227..1b8376fdc2 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -16,8 +16,8 @@ env: jobs: - py38-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 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-resource-detector-container -- -ra + run: tox -e py38-test-instrumentation-openai-v2-0 -- -ra - py39-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 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-resource-detector-container -- -ra + run: tox -e py38-test-instrumentation-openai-v2-1 -- -ra - py310-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 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-resource-detector-container -- -ra + run: tox -e py39-test-instrumentation-openai-v2-0 -- -ra - py311-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 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-resource-detector-container -- -ra + run: tox -e py39-test-instrumentation-openai-v2-1 -- -ra - py312-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 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-resource-detector-container -- -ra + run: tox -e py310-test-instrumentation-openai-v2-0 -- -ra - pypy3-test-resource-detector-container_ubuntu-latest: - name: resource-detector-container 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-resource-detector-container -- -ra + run: tox -e py310-test-instrumentation-openai-v2-1 -- -ra - py38-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 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-azure -- -ra + run: tox -e py311-test-instrumentation-openai-v2-0 -- -ra - py39-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 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-azure -- -ra + run: tox -e py311-test-instrumentation-openai-v2-1 -- -ra - py310-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 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-azure -- -ra + run: tox -e py312-test-instrumentation-openai-v2-0 -- -ra - py311-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 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-azure -- -ra + run: tox -e py312-test-instrumentation-openai-v2-1 -- -ra - py312-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 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-azure -- -ra + run: tox -e pypy3-test-instrumentation-openai-v2-0 -- -ra - pypy3-test-resource-detector-azure_ubuntu-latest: - name: resource-detector-azure 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-azure -- -ra + run: tox -e pypy3-test-instrumentation-openai-v2-1 -- -ra - py38-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 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-sdk-extension-aws -- -ra + run: tox -e py38-test-resource-detector-container -- -ra - py39-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 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-sdk-extension-aws -- -ra + run: tox -e py39-test-resource-detector-container -- -ra - py310-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 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-sdk-extension-aws -- -ra + run: tox -e py310-test-resource-detector-container -- -ra - py311-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 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-sdk-extension-aws -- -ra + run: tox -e py311-test-resource-detector-container -- -ra - py312-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 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-sdk-extension-aws -- -ra + run: tox -e py312-test-resource-detector-container -- -ra - pypy3-test-sdk-extension-aws_ubuntu-latest: - name: sdk-extension-aws 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-sdk-extension-aws -- -ra + run: tox -e pypy3-test-resource-detector-container -- -ra - py38-test-distro_ubuntu-latest: - name: distro 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-distro -- -ra + run: tox -e py38-test-resource-detector-azure-0 -- -ra - py39-test-distro_ubuntu-latest: - name: distro 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-distro -- -ra + run: tox -e py38-test-resource-detector-azure-1 -- -ra - py310-test-distro_ubuntu-latest: - name: distro 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-distro -- -ra + run: tox -e py39-test-resource-detector-azure-0 -- -ra - py311-test-distro_ubuntu-latest: - name: distro 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-distro -- -ra + run: tox -e py39-test-resource-detector-azure-1 -- -ra - py312-test-distro_ubuntu-latest: - name: distro 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-distro -- -ra + run: tox -e py310-test-resource-detector-azure-0 -- -ra - pypy3-test-distro_ubuntu-latest: - name: distro 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-distro -- -ra + run: tox -e py310-test-resource-detector-azure-1 -- -ra - py38-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 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-opentelemetry-instrumentation -- -ra + run: tox -e py311-test-resource-detector-azure-0 -- -ra - py39-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 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-opentelemetry-instrumentation -- -ra + run: tox -e py311-test-resource-detector-azure-1 -- -ra - py310-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 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-opentelemetry-instrumentation -- -ra + run: tox -e py312-test-resource-detector-azure-0 -- -ra - py311-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 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-opentelemetry-instrumentation -- -ra + run: tox -e py312-test-resource-detector-azure-1 -- -ra - py312-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 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-opentelemetry-instrumentation -- -ra + run: tox -e pypy3-test-resource-detector-azure-0 -- -ra - pypy3-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 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-opentelemetry-instrumentation -- -ra + run: tox -e pypy3-test-resource-detector-azure-1 -- -ra - py38-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 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-instrumentation-aiohttp-client -- -ra + run: tox -e py38-test-sdk-extension-aws-0 -- -ra - py39-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 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-instrumentation-aiohttp-client -- -ra + run: tox -e py38-test-sdk-extension-aws-1 -- -ra - py310-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 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-instrumentation-aiohttp-client -- -ra + run: tox -e py39-test-sdk-extension-aws-0 -- -ra - py311-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 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-instrumentation-aiohttp-client -- -ra + run: tox -e py39-test-sdk-extension-aws-1 -- -ra - py312-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 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-instrumentation-aiohttp-client -- -ra + run: tox -e py310-test-sdk-extension-aws-0 -- -ra - pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 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-instrumentation-aiohttp-client -- -ra + run: tox -e py310-test-sdk-extension-aws-1 -- -ra - py38-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 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-server -- -ra + run: tox -e py311-test-sdk-extension-aws-0 -- -ra - py39-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 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-server -- -ra + run: tox -e py311-test-sdk-extension-aws-1 -- -ra - py310-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 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-server -- -ra + run: tox -e py312-test-sdk-extension-aws-0 -- -ra - py311-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 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-server -- -ra + run: tox -e py312-test-sdk-extension-aws-1 -- -ra - py312-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 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-server -- -ra + run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra - pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 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-server -- -ra + run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra - py38-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 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-aiopg -- -ra + run: tox -e py38-test-distro -- -ra - py39-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 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-aiopg -- -ra + run: tox -e py39-test-distro -- -ra - py310-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 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-aiopg -- -ra + run: tox -e py310-test-distro -- -ra - py311-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 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-aiopg -- -ra + run: tox -e py311-test-distro -- -ra - py312-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 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,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aiopg -- -ra + run: tox -e py312-test-distro -- -ra - py38-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 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 }} + 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 }} @@ -878,10 +896,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-aws-lambda -- -ra + run: tox -e py38-test-opentelemetry-instrumentation -- -ra - py39-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 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 }} @@ -896,10 +914,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra + run: tox -e py39-test-opentelemetry-instrumentation -- -ra - py310-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 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 }} @@ -914,10 +932,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-aws-lambda -- -ra + run: tox -e py310-test-opentelemetry-instrumentation -- -ra - py311-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 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 }} @@ -932,10 +950,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-aws-lambda -- -ra + run: tox -e py311-test-opentelemetry-instrumentation -- -ra - py312-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 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 }} @@ -950,10 +968,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-aws-lambda -- -ra + run: tox -e py312-test-opentelemetry-instrumentation -- -ra - pypy3-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda pypy-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 }} @@ -968,10 +986,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra + run: tox -e pypy3-test-opentelemetry-instrumentation -- -ra - py38-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 3.8 Ubuntu + 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-botocore -- -ra + run: tox -e py38-test-instrumentation-aiohttp-client -- -ra - py39-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 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-botocore -- -ra + run: tox -e py39-test-instrumentation-aiohttp-client -- -ra - py310-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 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-botocore -- -ra + run: tox -e py310-test-instrumentation-aiohttp-client -- -ra - py311-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 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-botocore -- -ra + run: tox -e py311-test-instrumentation-aiohttp-client -- -ra - py312-test-instrumentation-botocore_ubuntu-latest: - name: instrumentation-botocore 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,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-botocore -- -ra + run: tox -e py312-test-instrumentation-aiohttp-client -- -ra - py38-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 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 }} + 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 }} @@ -1076,10 +1112,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-boto3sqs -- -ra + run: tox -e py38-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 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 }} @@ -1094,10 +1130,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra + run: tox -e py39-test-instrumentation-aiohttp-server -- -ra - py310-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 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 }} @@ -1112,10 +1148,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-boto3sqs -- -ra + run: tox -e py310-test-instrumentation-aiohttp-server -- -ra - py311-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 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 }} @@ -1130,10 +1166,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-boto3sqs -- -ra + run: tox -e py311-test-instrumentation-aiohttp-server -- -ra - py312-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 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 }} @@ -1148,10 +1184,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-boto3sqs -- -ra + run: tox -e py312-test-instrumentation-aiohttp-server -- -ra - pypy3-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs pypy-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 }} @@ -1166,10 +1202,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra + run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra - py38-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.8 Ubuntu + py38-test-instrumentation-aiopg_ubuntu-latest: + name: instrumentation-aiopg 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1184,118 +1220,118 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-django-0 -- -ra + run: tox -e py38-test-instrumentation-aiopg -- -ra - py38-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.8 Ubuntu + 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.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-1 -- -ra + run: tox -e py39-test-instrumentation-aiopg -- -ra - py38-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.8 Ubuntu + 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.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-2 -- -ra + run: tox -e py310-test-instrumentation-aiopg -- -ra - py39-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.9 Ubuntu + 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.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-django-0 -- -ra + run: tox -e py311-test-instrumentation-aiopg -- -ra - py39-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.9 Ubuntu + 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.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-1 -- -ra + run: tox -e py312-test-instrumentation-aiopg -- -ra - py39-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.9 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 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-aws-lambda -- -ra - py310-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.10 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.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-aws-lambda -- -ra - py310-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.10 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 }} @@ -1310,10 +1346,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-django-3 -- -ra + run: tox -e py310-test-instrumentation-aws-lambda -- -ra - py311-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.11 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 }} @@ -1328,280 +1364,262 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-django-1 -- -ra + run: tox -e py311-test-instrumentation-aws-lambda -- -ra - py311-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.11 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.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-aws-lambda -- -ra - py312-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.12 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.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-django-1 -- -ra + run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - py312-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.12 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.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-3 -- -ra + run: tox -e py38-test-instrumentation-botocore -- -ra - pypy3-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 pypy-3.8 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 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-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 + run: tox -e py39-test-instrumentation-botocore -- -ra - py38-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.8 Ubuntu + 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.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-dbapi -- -ra + run: tox -e py310-test-instrumentation-botocore -- -ra - py39-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.9 Ubuntu + 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.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-dbapi -- -ra + run: tox -e py311-test-instrumentation-botocore -- -ra - py310-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.10 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.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-dbapi -- -ra + run: tox -e py312-test-instrumentation-botocore -- -ra - py311-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.11 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.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-boto3sqs -- -ra - py312-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 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-dbapi -- -ra + run: tox -e py39-test-instrumentation-boto3sqs -- -ra - pypy3-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 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-dbapi -- -ra + run: tox -e py310-test-instrumentation-boto3sqs -- -ra - py38-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 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 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-boto -- -ra + run: tox -e py311-test-instrumentation-boto3sqs -- -ra - py39-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.9 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.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-boto -- -ra + run: tox -e py312-test-instrumentation-boto3sqs -- -ra - py310-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.10 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.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-boto -- -ra + run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra - py311-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.11 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.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-boto -- -ra + run: tox -e py38-test-instrumentation-django-0 -- -ra - py38-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.8 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 }} @@ -1616,10 +1634,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py38-test-instrumentation-django-1 -- -ra - py38-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.8 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 }} @@ -1634,28 +1652,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py38-test-instrumentation-django-2 -- -ra - py38-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 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 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-elasticsearch-2 -- -ra + run: tox -e py39-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.9 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 }} @@ -1670,10 +1688,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py39-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 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 }} @@ -1688,28 +1706,28 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py39-test-instrumentation-django-2 -- -ra - py39-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.9 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 }} 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-elasticsearch-2 -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py310-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.10 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 }} @@ -1724,226 +1742,226 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py310-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.10 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.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-elasticsearch-1 -- -ra + run: tox -e py311-test-instrumentation-django-1 -- -ra - py310-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.10 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.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-elasticsearch-2 -- -ra + run: tox -e py311-test-instrumentation-django-3 -- -ra - py311-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.11 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.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-elasticsearch-0 -- -ra + run: tox -e py312-test-instrumentation-django-1 -- -ra - py311-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.11 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.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-elasticsearch-1 -- -ra + run: tox -e py312-test-instrumentation-django-3 -- -ra - py311-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.11 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.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-elasticsearch-2 -- -ra + run: tox -e pypy3-test-instrumentation-django-0 -- -ra - py312-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.12 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.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-0 -- -ra + run: tox -e pypy3-test-instrumentation-django-1 -- -ra - py312-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.12 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.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-1 -- -ra + run: tox -e py38-test-instrumentation-dbapi -- -ra - py312-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.12 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.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-elasticsearch-2 -- -ra + run: tox -e py39-test-instrumentation-dbapi -- -ra - pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.8 Ubuntu + 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 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-0 -- -ra + run: tox -e py310-test-instrumentation-dbapi -- -ra - pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.8 Ubuntu + 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 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-1 -- -ra + run: tox -e py311-test-instrumentation-dbapi -- -ra - pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.8 Ubuntu + 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 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-elasticsearch-2 -- -ra + run: tox -e py312-test-instrumentation-dbapi -- -ra - py38-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.8 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.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-falcon-0 -- -ra + run: tox -e pypy3-test-instrumentation-dbapi -- -ra - py38-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.8 Ubuntu + py38-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.8 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -1958,316 +1976,316 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-falcon-1 -- -ra + run: tox -e py38-test-instrumentation-boto -- -ra - py38-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 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 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-falcon-2 -- -ra + run: tox -e py39-test-instrumentation-boto -- -ra - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 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 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-falcon-0 -- -ra + run: tox -e py310-test-instrumentation-boto -- -ra - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 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 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-falcon-1 -- -ra + run: tox -e py311-test-instrumentation-boto -- -ra - py39-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.9 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 }} 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-falcon-2 -- -ra + run: tox -e py38-test-instrumentation-elasticsearch-0 -- -ra - py310-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.10 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 }} 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-falcon-1 -- -ra + run: tox -e py38-test-instrumentation-elasticsearch-1 -- -ra - py310-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.10 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 }} 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-falcon-2 -- -ra + run: tox -e py38-test-instrumentation-elasticsearch-2 -- -ra - py311-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.11 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 }} 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-falcon-1 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra - py311-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.11 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 }} 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-falcon-2 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra - py312-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.12 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 }} 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-falcon-1 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - py312-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.12 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 }} 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-falcon-2 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - pypy3-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 pypy-3.8 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 }} 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-falcon-0 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra - pypy3-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 pypy-3.8 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 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-falcon-1 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - pypy3-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 pypy-3.8 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 }} 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-2 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra - py38-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.8 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.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-fastapi -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra - py39-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.9 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 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-fastapi -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra - py310-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.10 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 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-fastapi -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra - py311-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.11 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 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-fastapi -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra - py312-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.12 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 }} @@ -2282,10 +2300,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-fastapi -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra - pypy3-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi pypy-3.8 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 }} @@ -2300,280 +2318,280 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-fastapi -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra - py38-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.8 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.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-0 -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra - py38-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.8 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.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-1 -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.9 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.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-flask-0 -- -ra + run: tox -e py38-test-instrumentation-falcon-0 -- -ra - py39-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.9 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 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-flask-1 -- -ra + run: tox -e py38-test-instrumentation-falcon-1 -- -ra - py310-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.10 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 }} 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-flask-0 -- -ra + run: tox -e py38-test-instrumentation-falcon-2 -- -ra - py310-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.10 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.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-flask-1 -- -ra + run: tox -e py39-test-instrumentation-falcon-0 -- -ra - py311-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.11 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 }} 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-flask-0 -- -ra + run: tox -e py39-test-instrumentation-falcon-1 -- -ra - py311-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.11 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 }} 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-flask-1 -- -ra + run: tox -e py39-test-instrumentation-falcon-2 -- -ra - py312-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.12 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 }} 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-flask-0 -- -ra + run: tox -e py310-test-instrumentation-falcon-1 -- -ra - py312-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.12 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 }} 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-flask-1 -- -ra + run: tox -e py310-test-instrumentation-falcon-2 -- -ra - py38-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.8 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 }} 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-flask-2 -- -ra + run: tox -e py311-test-instrumentation-falcon-1 -- -ra - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 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 }} 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-flask-2 -- -ra + run: tox -e py311-test-instrumentation-falcon-2 -- -ra - py310-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.10 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 }} 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-flask-2 -- -ra + run: tox -e py312-test-instrumentation-falcon-1 -- -ra - py311-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.11 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 }} 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-flask-2 -- -ra + run: tox -e py312-test-instrumentation-falcon-2 -- -ra - py312-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.12 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.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-flask-2 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra - pypy3-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 pypy-3.8 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 }} @@ -2588,10 +2606,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-0 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra - pypy3-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 pypy-3.8 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 }} @@ -2606,10 +2624,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-1 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra - py38-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 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 }} @@ -2624,10 +2642,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-urllib -- -ra + run: tox -e py38-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 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 }} @@ -2642,10 +2660,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra + run: tox -e py39-test-instrumentation-fastapi -- -ra - py310-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 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 }} @@ -2660,10 +2678,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-urllib -- -ra + run: tox -e py310-test-instrumentation-fastapi -- -ra - py311-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 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 }} @@ -2678,10 +2696,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-urllib -- -ra + run: tox -e py311-test-instrumentation-fastapi -- -ra - py312-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 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 }} @@ -2696,10 +2714,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-urllib -- -ra + run: tox -e py312-test-instrumentation-fastapi -- -ra - pypy3-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 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 }} @@ -2714,10 +2732,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib -- -ra + run: tox -e pypy3-test-instrumentation-fastapi -- -ra - py38-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.8 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 }} @@ -2732,10 +2750,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-urllib3-0 -- -ra + run: tox -e py38-test-instrumentation-flask-0 -- -ra - py38-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.8 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 }} @@ -2750,10 +2768,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-urllib3-1 -- -ra + run: tox -e py38-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.9 Ubuntu + 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 }} @@ -2768,10 +2786,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py39-test-instrumentation-flask-0 -- -ra - py39-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.9 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 }} @@ -2786,10 +2804,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py39-test-instrumentation-flask-1 -- -ra - py310-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.10 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 }} @@ -2804,10 +2822,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-flask-0 -- -ra - py310-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.10 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 }} @@ -2822,10 +2840,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-flask-1 -- -ra - py311-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.11 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 }} @@ -2840,10 +2858,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-flask-0 -- -ra - py311-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.11 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 }} @@ -2858,10 +2876,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-1 -- -ra + run: tox -e py311-test-instrumentation-flask-1 -- -ra - py312-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 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 }} @@ -2876,10 +2894,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-0 -- -ra + run: tox -e py312-test-instrumentation-flask-0 -- -ra - py312-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.12 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 }} @@ -2894,136 +2912,136 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-1 -- -ra + run: tox -e py312-test-instrumentation-flask-1 -- -ra - pypy3-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 pypy-3.8 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 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-urllib3-0 -- -ra + run: tox -e py38-test-instrumentation-flask-2 -- -ra - pypy3-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 pypy-3.8 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 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-urllib3-1 -- -ra + run: tox -e py39-test-instrumentation-flask-2 -- -ra - py38-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.8 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.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-requests -- -ra + run: tox -e py310-test-instrumentation-flask-2 -- -ra - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 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.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-requests -- -ra + run: tox -e py311-test-instrumentation-flask-2 -- -ra - py310-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.10 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.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-requests -- -ra + run: tox -e py312-test-instrumentation-flask-2 -- -ra - py311-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.11 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 }} 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-requests -- -ra + run: tox -e pypy3-test-instrumentation-flask-0 -- -ra - py312-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.12 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 }} 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-requests -- -ra + run: tox -e pypy3-test-instrumentation-flask-1 -- -ra - py38-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 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 }} @@ -3038,10 +3056,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-starlette -- -ra + run: tox -e py38-test-instrumentation-urllib -- -ra - py39-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 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 }} @@ -3056,10 +3074,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-starlette -- -ra + run: tox -e py39-test-instrumentation-urllib -- -ra - py310-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 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 }} @@ -3074,10 +3092,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-starlette -- -ra + run: tox -e py310-test-instrumentation-urllib -- -ra - py311-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 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 }} @@ -3092,10 +3110,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-starlette -- -ra + run: tox -e py311-test-instrumentation-urllib -- -ra - py312-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette 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 }} @@ -3110,10 +3128,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-starlette -- -ra + run: tox -e py312-test-instrumentation-urllib -- -ra - pypy3-test-instrumentation-starlette_ubuntu-latest: - name: instrumentation-starlette pypy-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 }} @@ -3128,10 +3146,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette -- -ra + run: tox -e pypy3-test-instrumentation-urllib -- -ra - py38-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.8 Ubuntu + 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-jinja2 -- -ra + run: tox -e py38-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 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-jinja2 -- -ra + run: tox -e py38-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 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-jinja2 -- -ra + run: tox -e py39-test-instrumentation-urllib3-0 -- -ra - py311-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 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-jinja2 -- -ra + run: tox -e py39-test-instrumentation-urllib3-1 -- -ra - py312-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 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-jinja2 -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 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-jinja2 -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py38-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 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-logging -- -ra + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 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-logging -- -ra + run: tox -e py311-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 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-logging -- -ra + run: tox -e py312-test-instrumentation-urllib3-0 -- -ra - py311-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 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-logging -- -ra + run: tox -e py312-test-instrumentation-urllib3-1 -- -ra - py312-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 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-logging -- -ra + run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra - pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 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-logging -- -ra + run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra - py38-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 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-exporter-richconsole -- -ra + run: tox -e py38-test-instrumentation-requests -- -ra - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 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-exporter-richconsole -- -ra + run: tox -e py39-test-instrumentation-requests -- -ra - py310-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 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-exporter-richconsole -- -ra + run: tox -e py310-test-instrumentation-requests -- -ra - py311-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 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-exporter-richconsole -- -ra + run: tox -e py311-test-instrumentation-requests -- -ra - py312-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 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-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 + run: tox -e py312-test-instrumentation-requests -- -ra - py38-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 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-prometheus-remote-write -- -ra + run: tox -e py38-test-instrumentation-starlette -- -ra - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 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-prometheus-remote-write -- -ra + run: tox -e py39-test-instrumentation-starlette -- -ra - py310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 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-prometheus-remote-write -- -ra + run: tox -e py310-test-instrumentation-starlette -- -ra - py311-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 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-prometheus-remote-write -- -ra + run: tox -e py311-test-instrumentation-starlette -- -ra - py312-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 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-prometheus-remote-write -- -ra + run: tox -e py312-test-instrumentation-starlette -- -ra - pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 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-prometheus-remote-write -- -ra + run: tox -e pypy3-test-instrumentation-starlette -- -ra - py38-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 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,190 +3578,190 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-mysql-0 -- -ra + run: tox -e py38-test-instrumentation-jinja2 -- -ra - py38-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 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 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-jinja2 -- -ra - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 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 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-jinja2 -- -ra - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 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.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-jinja2 -- -ra - py310-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.10 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.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-jinja2 -- -ra - py310-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.10 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.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-jinja2 -- -ra - py311-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.11 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.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-instrumentation-logging -- -ra - py311-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.11 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.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-instrumentation-logging -- -ra - py312-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.12 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.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-instrumentation-logging -- -ra - py312-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.12 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.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-instrumentation-logging -- -ra - pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.8 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 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-instrumentation-logging -- -ra - pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.8 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 }} @@ -3776,10 +3776,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-instrumentation-logging -- -ra - py38-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 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 }} @@ -3794,10 +3794,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py38-test-instrumentation-mysqlclient -- -ra + run: tox -e py38-test-exporter-richconsole -- -ra - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 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 }} @@ -3812,10 +3812,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra + run: tox -e py39-test-exporter-richconsole -- -ra - py310-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 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 }} @@ -3830,10 +3830,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py310-test-instrumentation-mysqlclient -- -ra + run: tox -e py310-test-exporter-richconsole -- -ra - py311-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 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 }} @@ -3848,10 +3848,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-mysqlclient -- -ra + run: tox -e py311-test-exporter-richconsole -- -ra - py312-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 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 }} @@ -3866,10 +3866,10 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-mysqlclient -- -ra + run: tox -e py312-test-exporter-richconsole -- -ra - pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 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-mysqlclient -- -ra + run: tox -e pypy3-test-exporter-richconsole -- -ra - py38-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 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-psycopg2 -- -ra + run: tox -e py38-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 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-psycopg2 -- -ra + run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - py310-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 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-psycopg2 -- -ra + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - py311-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 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-psycopg2 -- -ra + run: tox -e py311-test-exporter-prometheus-remote-write -- -ra - py312-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 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,262 +3974,262 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2 -- -ra + run: tox -e py312-test-exporter-prometheus-remote-write -- -ra - py38-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 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 }} 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-psycopg -- -ra + run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 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-psycopg -- -ra + run: tox -e py38-test-instrumentation-mysql-0 -- -ra - py310-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.10 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.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-psycopg -- -ra + run: tox -e py38-test-instrumentation-mysql-1 -- -ra - py311-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.11 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.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-psycopg -- -ra + run: tox -e py39-test-instrumentation-mysql-0 -- -ra - py312-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.12 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.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-psycopg -- -ra + run: tox -e py39-test-instrumentation-mysql-1 -- -ra - pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.8 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 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-psycopg -- -ra + run: tox -e py310-test-instrumentation-mysql-0 -- -ra - py38-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 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-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-mysql-1 -- -ra - py38-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.8 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.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-1 -- -ra + run: tox -e py311-test-instrumentation-mysql-0 -- -ra - py38-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.8 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.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-2 -- -ra + run: tox -e py311-test-instrumentation-mysql-1 -- -ra - py38-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.8 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.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-pymemcache-3 -- -ra + run: tox -e py312-test-instrumentation-mysql-0 -- -ra - py38-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.8 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.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-pymemcache-4 -- -ra + run: tox -e py312-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 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.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-0 -- -ra + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 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.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-mysql-1 -- -ra - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 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.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-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu runs-on: ubuntu-latest steps: - name: Checkout repo @ SHA - ${{ github.sha }} @@ -4244,136 +4244,136 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py39-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 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.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-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 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.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-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 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.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-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 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.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-pymemcache-2 -- -ra + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.10 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.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-3 -- -ra + run: tox -e py38-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.10 Ubuntu + 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.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-4 -- -ra + run: tox -e py39-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.11 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.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-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 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 }} @@ -4388,100 +4388,100 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py311-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.11 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.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-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.11 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.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-pymemcache-3 -- -ra + run: tox -e py38-test-instrumentation-psycopg -- -ra - py311-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.11 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.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-pymemcache-4 -- -ra + run: tox -e py39-test-instrumentation-psycopg -- -ra - py312-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.12 Ubuntu + 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.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-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-psycopg -- -ra - py312-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.12 Ubuntu + 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.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-pymemcache-1 -- -ra + run: tox -e py311-test-instrumentation-psycopg -- -ra - py312-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 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 }} @@ -4496,22 +4496,22 @@ jobs: run: pip install tox - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py312-test-instrumentation-psycopg -- -ra - py312-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.12 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.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-3 -- -ra + run: tox -e pypy3-test-instrumentation-psycopg -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 30ca4e67d2..227c891d0b 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -16,6 +16,438 @@ 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 + 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 @@ -1060,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 @@ -1078,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 @@ -1096,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 @@ -1114,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 @@ -1132,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 @@ -1168,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 @@ -2230,8 +2770,26 @@ 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 }} + 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-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 }} @@ -2246,10 +2804,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-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 + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-0 -- -ra - py39-test-propagator-aws-xray_ubuntu-latest: - name: propagator-aws-xray 3.9 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 }} @@ -2264,10 +2840,28 @@ 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-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 }} @@ -2282,10 +2876,28 @@ 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-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_ubuntu-latest: - name: propagator-aws-xray 3.11 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 }} @@ -2300,10 +2912,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-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_ubuntu-latest: - name: propagator-aws-xray 3.12 Ubuntu + 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 }} @@ -2318,10 +2948,28 @@ 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-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 }} @@ -2336,7 +2984,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/.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/CHANGELOG.md b/CHANGELOG.md index 31aa265602..6fdb7c123f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,24 +13,64 @@ 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 + +- `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)) + +## Version 1.28.0/0.49b0 (2024-11-05) + +### Added + +- `opentelemetry-instrumentation-openai-v2` Instrumentation for OpenAI >= 0.27.0 + ([#2759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2759)) - `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)) - `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 - `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) +- `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)) +- `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)) +- `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 + +- 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)) +- `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) ### 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)) @@ -74,6 +114,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) @@ -232,7 +275,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)) @@ -247,6 +290,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 @@ -264,8 +308,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)) @@ -276,7 +320,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) @@ -360,6 +404,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)) @@ -404,8 +449,11 @@ 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 + - `opentelemetry-instrumentation-kafka-python` Add instrumentation to `consume` method ([#1786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1786)) @@ -456,6 +504,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)) @@ -493,7 +542,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. @@ -517,7 +566,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)) @@ -569,7 +618,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)) @@ -654,7 +703,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 @@ -667,7 +715,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)) @@ -686,6 +734,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)) @@ -698,11 +747,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). @@ -715,8 +764,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 @@ -740,10 +789,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) @@ -756,6 +805,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). @@ -763,22 +813,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)) @@ -812,7 +863,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 @@ -826,7 +876,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 @@ -865,12 +915,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)) @@ -904,12 +953,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 @@ -979,13 +1027,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)) @@ -999,7 +1048,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` @@ -1026,6 +1077,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` @@ -1056,6 +1108,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`, @@ -1074,10 +1127,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. @@ -1125,12 +1180,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. @@ -1147,6 +1204,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)) @@ -1156,6 +1214,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)) @@ -1707,6 +1766,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) @@ -1721,7 +1781,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/CONTRIBUTING.md b/CONTRIBUTING.md index 61f261f001..a0cdbfa8ec 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) +* [Guideline for GenAI instrumentations](#guideline-for-genai-instrumentations) * [Expectations from contributors](#expectations-from-contributors) ## Find a Buddy and get Started Quickly @@ -67,20 +68,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 @@ -277,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. +## 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. + +### 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/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. + +* 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/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/_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/_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/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/eachdist.ini b/eachdist.ini index 950b751685..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 @@ -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/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..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 @@ -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, @@ -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/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-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-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): 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/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/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-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md new file mode 100644 index 0000000000..2fdeeea74f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -0,0 +1,21 @@ +# 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.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. + ([#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)) + +- 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-test/LICENSE b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/LICENSE similarity index 100% rename from instrumentation/opentelemetry-instrumentation-test/LICENSE rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/LICENSE diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst new file mode 100644 index 0000000000..85817896ff --- /dev/null +++ b/instrumentation-genai/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-test/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml similarity index 69% rename from instrumentation/opentelemetry-instrumentation-test/pyproject.toml rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index 78e12624d0..eddd85e5f0 100644 --- a/instrumentation/opentelemetry-instrumentation-test/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -3,9 +3,9 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "opentelemetry-instrumentation-test" +name = "opentelemetry-instrumentation-openai-v2" dynamic = ["version"] -description = "test Middleware for OpenTelemetry" +description = "OpenTelemetry Official OpenAI instrumentation" readme = "README.rst" license = "Apache-2.0" requires-python = ">=3.8" @@ -25,19 +25,24 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation ~= 0.47b0", - "opentelemetry-semantic-conventions == 0.47b0", + "opentelemetry-api ~= 1.28", + "opentelemetry-instrumentation ~= 0.49b0", + "opentelemetry-semantic-conventions ~= 0.49b0" ] [project.optional-dependencies] -instruments = [] +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-test" +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-openai-v2" [tool.hatch.version] -path = "src/opentelemetry/instrumentation/test/version.py" +path = "src/opentelemetry/instrumentation/openai_v2/version.py" [tool.hatch.build.targets.sdist] include = [ 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 new file mode 100644 index 0000000000..e8a782e404 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -0,0 +1,90 @@ +# 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_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."}, + ], + ) + +API +--- +""" + +from typing import Collection + +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 + +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_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, event_logger, is_content_enabled() + ), + ) + + def _uninstrument(self, **kwargs): + import openai # pylint: disable=import-outside-toplevel + + unwrap(openai.resources.chat.completions.Completions, "create") diff --git a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py similarity index 87% rename from instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py index 361eac89c9..b53e25f7df 100644 --- a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/package.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/package.py @@ -13,8 +13,4 @@ # limitations under the License. -_instruments = tuple() - -_supports_metrics = False - -_semconv_status = "migration" +_instruments = ("openai >= 1.26.0",) 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 new file mode 100644 index 0000000000..8540bff219 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -0,0 +1,380 @@ +# 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 Optional + +from openai import Stream + +from opentelemetry._events import Event, EventLogger +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, + is_streaming, + message_to_event, + set_span_attribute, +) + + +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): + 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 = wrapped(*args, **kwargs) + if is_streaming(kwargs): + return StreamWrapper( + result, span, event_logger, capture_content + ) + + if span.is_recording(): + _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 + + return traced_method + + +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 + 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") + + set_span_attribute( + span, + GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, + finish_reasons, + ) + + 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( + 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 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: 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: Stream, + span: Span, + event_logger: EventLogger, + capture_content: bool, + ): + self.stream = stream + self.span = span + self.choice_buffers = [] + self._span_started = False + self.capture_content = capture_content + + self.event_logger = event_logger + 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_span_attribute( + self.span, + GenAIAttributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER, + self.service_tier, + ) + + set_span_attribute( + self.span, + 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 + + 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 close(self): + self.stream.close() + self.cleanup() + + 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 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 + for choice in choices: + if not choice.delta: + continue + + # 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): + 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.set_response_service_tier(chunk) + self.build_streaming_response(chunk) + self.set_usage(chunk) 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 new file mode 100644 index 0000000000..a3a2d317ce --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -0,0 +1,212 @@ +# 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 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_GENAI_CAPTURE_MESSAGE_CONTENT = ( + "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" +) + + +def is_content_enabled() -> bool: + capture_content = environ.get( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, "false" + ) + + return capture_content.lower() == "true" + + +def extract_tool_calls(item, capture_content): + tool_calls = get_property_value(item, "tool_calls") + if tool_calls is None: + return None + + calls = [] + for tool_call in tool_calls: + 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 + + calls.append(tool_call_dict) + return calls + + +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 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", + } + + 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 + + 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, + 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"), + 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" + ), + 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-test/src/opentelemetry/instrumentation/test/version.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py similarity index 95% rename from instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/version.py rename to instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/version.py index 0d3adda0a2..5b77207d9d 100644 --- a/instrumentation/opentelemetry-instrumentation-test/src/opentelemetry/instrumentation/test/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__ = "1.0.0b.dev" +__version__ = "2.1b0.dev" 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-1.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt new file mode 100644 index 0000000000..ded849c8ee --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-1.txt @@ -0,0 +1,12 @@ +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 +# 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/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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 new file mode 100644 index 0000000000..ae00c6ef70 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_404.yaml @@ -0,0 +1,87 @@ +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.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + 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: + - 8dd0709dffd19c8c-SIN + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 04 Nov 2024 00:20:44 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_e08854c4f7d5104af6fdc755caed30fc + status: + code: 404 + message: Not Found +version: 1 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 new file mode 100644 index 0000000000..cfcd27074a --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_extra_params.yaml @@ -0,0 +1,131 @@ +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 + connection: + - keep-alive + content-length: + - '183' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c2d0a5a9f98-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:37 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: + - '228' + 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: + - '9998' + x-ratelimit-remaining-tokens: + - '199943' + x-ratelimit-reset-requests: + - 13.724s + x-ratelimit-reset-tokens: + - 16ms + x-request-id: + - req_0ded46a4535c24c36ef58363b7538421 + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..9518e41225 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml @@ -0,0 +1,137 @@ +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.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c30beda3dd4-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:38 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: + - '261' + 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: + - '9997' + x-ratelimit-remaining-tokens: + - '199962' + x-ratelimit-reset-requests: + - 21.785s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_86ab6a7a85f95e2a001cfeb89e0827b1 + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..e587ce5a38 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml @@ -0,0 +1,336 @@ +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.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + 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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8dd07c55783bce06-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 04 Nov 2024 00:28:44 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: + - '127' + 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: + - '9993' + x-ratelimit-remaining-tokens: + - '199945' + x-ratelimit-reset-requests: + - 59.105s + x-ratelimit-reset-tokens: + - 16ms + x-request-id: + - req_4d50387aa59e08f2dc486aa5c62613f5 + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..8989eb9cfa --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml @@ -0,0 +1,162 @@ +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 + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + 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-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-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-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-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-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-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-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-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-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: + - 8dd07c715fd66beb-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 04 Nov 2024 00:28: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 + openai-organization: test_organization + openai-processing-ms: + - '647' + 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: + - '9991' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 1m11.934s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_66ecdeba3a9e89bbc2aa60243fb1fdfb + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..c39facccc5 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml @@ -0,0 +1,162 @@ +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 + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + 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-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-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-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-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-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-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-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-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-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: + - 8dd07c5d48f0ce22-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 04 Nov 2024 00:28:48 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: + - '2886' + 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: + - '9992' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 1m6.499s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_c887b8540fec8e4eadca5d56c78cc4e1 + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..713ea762e0 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming.yaml @@ -0,0 +1,115 @@ +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.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + 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-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-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-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-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: + - 8dd07c4b99b74927-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 04 Nov 2024 00:28:42 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: + - '157' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '10000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '9978' + x-ratelimit-reset-requests: + - 8.64s + x-ratelimit-reset-tokens: + - 132ms + x-request-id: + - req_72de20dac77a9535e3f47a6ec3a39ddc + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..bec0658770 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml @@ -0,0 +1,110 @@ +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 + connection: + - keep-alive + content-length: + - '99' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + 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-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-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-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-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: + - 8dd07c505e24cdf2-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 04 Nov 2024 00:28:43 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: + - '269' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '10000' + x-ratelimit-remaining-requests: + - '9998' + x-ratelimit-remaining-tokens: + - '9978' + x-ratelimit-reset-requests: + - 16.502s + x-ratelimit-reset-tokens: + - 132ms + x-request-id: + - req_04c174debe2eace86b1e2777d7ac7265 + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..b4d5acca4a --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml @@ -0,0 +1,331 @@ +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 + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c3f4ba7ce35-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:41 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: + - '984' + 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: + - '9994' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 45.38s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - 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_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 + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '746' + 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 + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c473cc4ce35-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:42 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: + - '731' + openai-organization: test_organization + openai-processing-ms: + - '380' + 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: + - '9993' + x-ratelimit-remaining-tokens: + - '199947' + x-ratelimit-reset-requests: + - 52.749s + x-ratelimit-reset-tokens: + - 15ms + x-request-id: + - req_f56de3d8b168900542a01b971b367a9f + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..fbf1abd640 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml @@ -0,0 +1,331 @@ +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 + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c349cb38bcb-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:39 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: + - '631' + 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: + - '9996' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 29.791s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - 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_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 + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '746' + 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 + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c3ad9138bcb-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:40 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: + - '731' + openai-organization: test_organization + openai-processing-ms: + - '390' + 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: + - '9995' + x-ratelimit-remaining-tokens: + - '199947' + x-ratelimit-reset-requests: + - 37.448s + x-ratelimit-reset-tokens: + - 15ms + x-request-id: + - req_525d3b9301fff00a98647143a9c26b6f + status: + code: 200 + message: OK +version: 1 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 new file mode 100644 index 0000000000..bb61c001fb --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -0,0 +1,126 @@ +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 + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + 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.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + 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: + - 8dd07c16eae44a1d-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 04 Nov 2024 00:28:34 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: + - '666' + openai-organization: test_organization + openai-processing-ms: + - '732' + 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_0bb3c9da7d953e477d1947130d2cf1df + 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 new file mode 100644 index 0000000000..84a9bf2692 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -0,0 +1,176 @@ +"""Unit tests configuration module.""" + +import json +import os + +import pytest +import yaml +from openai import OpenAI + +from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor +from opentelemetry.instrumentation.openai_v2.utils 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(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="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_GENAI_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_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") +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"]["openai-organization"] = "test_organization" + response["headers"]["Set-Cookie"] = "test_set_cookie" + return response 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 new file mode 100644 index 0000000000..c6cb19aa8d --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -0,0 +1,825 @@ +# 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, NotFoundError, 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_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"}] + + 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]) + + +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") + + with pytest.raises(APIConnectionError): + 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() +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"}] + + with pytest.raises(NotFoundError): + 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() +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 ( + 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( + 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, + "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 = 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 + + 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, + }, + }, + } diff --git a/instrumentation/README.md b/instrumentation/README.md index 6bb47f6f9c..fb601266ea 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -39,11 +39,10 @@ | [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 -| [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-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/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-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-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/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-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..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 @@ -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( @@ -71,7 +71,6 @@ async def do_request(): class TestAioHttpIntegration(TestBase): - _test_status_codes = ( (HTTPStatus.OK, StatusCode.UNSET), (HTTPStatus.TEMPORARY_REDIRECT, StatusCode.UNSET), @@ -886,9 +885,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/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-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-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/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/__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-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/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/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-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-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/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/__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-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-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/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/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index e83f384a8c..2d1b063dfd 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -76,7 +76,9 @@ def func(): API --- """ + import asyncio +import functools import sys from asyncio import futures from timeit import default_timer @@ -163,7 +165,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: @@ -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/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/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-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-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-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") 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/__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-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-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/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/__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/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-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-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-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-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/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/__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-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-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/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/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-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-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/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-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/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/__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/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-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-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): 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/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index 3d1cc79c93..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): @@ -363,7 +354,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/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-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-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") 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-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/__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/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-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-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): 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/__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/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/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-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-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" ) 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-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-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/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/__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-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-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/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-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..fdbad4effb 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,33 @@ 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") - def test_instruments_without_fastapi_installed( - self, mock_get_distribution - ): - mock_get_distribution.side_effect = get_distribution_without_fastapi + @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_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-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/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 0e74ca331f..d5a27c78e7 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -26,12 +26,11 @@ 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", - "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..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 @@ -245,7 +246,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 +272,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 +289,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/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-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/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/__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-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-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/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 599091716b..e4479223a4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -26,9 +26,10 @@ 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", ] [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 15ee59a183..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 ----- @@ -190,12 +191,15 @@ async def async_response_hook(span, request, response): API --- """ + 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, @@ -216,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 @@ -306,7 +311,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 +562,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, ]: @@ -728,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[ @@ -785,86 +959,105 @@ 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( - client: typing.Union[httpx.Client, httpx.AsyncClient] + client: typing.Union[httpx.Client, httpx.AsyncClient], ): """Disables instrumentation for the given client instance 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/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-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-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 27535800cb..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() @@ -911,7 +918,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), @@ -930,8 +936,6 @@ def test_instrumentation_without_client(self): self.URL, ) - HTTPXClientInstrumentor().uninstrument() - def test_uninstrument(self): HTTPXClientInstrumentor().instrument() HTTPXClientInstrumentor().uninstrument() @@ -981,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() @@ -1000,7 +1002,6 @@ def test_instrument_client_with_proxy(self): self.assert_proxy_mounts( client._mounts.values(), 2, - (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), ) HTTPXClientInstrumentor().uninstrument_client(client) @@ -1011,7 +1012,6 @@ def test_uninstrument_client_with_proxy(self): self.assert_proxy_mounts( client._mounts.values(), 2, - (SyncOpenTelemetryTransport, AsyncOpenTelemetryTransport), ) HTTPXClientInstrumentor().uninstrument_client(client) @@ -1181,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) @@ -1189,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, @@ -1246,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( @@ -1259,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) + ) 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-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/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/__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-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-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/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/__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/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-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-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-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-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/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-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/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-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/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/__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-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-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/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-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/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-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-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/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/__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-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-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/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-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/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/__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-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-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/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/__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-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-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/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/__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-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-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/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-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/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index d6cc3f71d9..d6d8c7aff9 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -26,15 +26,15 @@ 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", ] [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/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py index 99bd23c65e..0b5e14b929 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-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/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-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-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 ca7c38d7d4..a5aa62e371 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) @@ -198,7 +203,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(), @@ -218,7 +223,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(), @@ -244,7 +249,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) @@ -269,7 +274,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 @@ -310,7 +315,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(), @@ -341,7 +346,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(), @@ -357,7 +362,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) @@ -370,10 +375,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) @@ -382,7 +387,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) @@ -395,13 +400,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) @@ -412,7 +417,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) @@ -431,7 +436,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/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-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/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/__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-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-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/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/__init__.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/__init__.py index 1b9a36c4cb..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 @@ -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: @@ -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/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-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-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}) 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/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/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt deleted file mode 100644 index 743026e94a..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/test-requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100644 index a0b2062b52..0000000000 --- a/instrumentation/opentelemetry-instrumentation-test/tests/__init__.py +++ /dev/null @@ -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/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-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/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/__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-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-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/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/__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-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-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/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/__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/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-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-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/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/__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-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-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/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/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/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-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index b34226b669..11eae92ba6 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -29,55 +29,54 @@ 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-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-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-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-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..f8aad72f4a 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.4", - "opentelemetry-semantic-conventions >= 0.48b0", - "setuptools >= 16.0", + "opentelemetry-semantic-conventions == 0.50b0.dev", "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..3d602b2a1d 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", @@ -86,18 +113,29 @@ 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 - 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", @@ -110,7 +148,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/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index 1cc28abca4..cc0ac68f1c 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -22,14 +22,21 @@ SubprocessError, check_call, ) +from typing import Optional -import pkg_resources +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 ( + PackageNotFoundError, + version, +) logger = logging.getLogger(__name__) @@ -71,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.' @@ -91,24 +98,25 @@ 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 -def _find_installed_libraries(): +def _find_installed_libraries(default_instrumentations, libraries): for lib in default_instrumentations: yield lib @@ -117,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" @@ -158,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/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index ff6065d058..2e7b5532f3 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -18,184 +18,183 @@ 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", + "library": "sqlalchemy >= 1.0.0, < 2.1.0", + "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-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-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", ] 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..1b450f2549 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__) @@ -33,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/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/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/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..ce9abe1365 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,11 +31,9 @@ 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 - ): # 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" @@ -61,11 +60,9 @@ 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 - ): # 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() @@ -74,7 +71,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 +98,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 +131,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 +163,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 +178,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 +208,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,11 +282,9 @@ 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 - ): # 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" @@ -314,3 +309,101 @@ def test_load_instrumentors_dep_conflict( ] ) 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) + # 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/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_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() 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..9801264cbe 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,11 @@ 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 +50,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/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)) 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-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/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/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 8f5b428ba4..679800462e 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.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 @@ -16,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/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/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/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/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/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 fe04c99490..a2344e2871 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-azure/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 @@ -9,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/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/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/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/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 ) 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 3b44b54a61..0861269324 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/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 @@ -11,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/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/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/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..cc5e509abc 100644 --- a/tox.ini +++ b/tox.ini @@ -6,19 +6,24 @@ 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-{0,1} + pypy3-test-instrumentation-openai-v2-{0,1} + lint-instrumentation-openai-v2 + ; opentelemetry-resource-detector-container py3{8,9,10,11,12}-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 - 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 @@ -258,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 @@ -312,8 +318,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 @@ -379,6 +385,7 @@ envlist = generate generate-workflows shellcheck + ruff [testenv] deps = @@ -404,6 +411,17 @@ 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 + # 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 distro: pip install opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk @@ -729,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 @@ -754,11 +773,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 @@ -767,11 +791,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 @@ -779,11 +808,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 @@ -804,362 +838,188 @@ 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-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: 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 @@ -1182,17 +1042,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 @@ -1234,7 +1083,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 @@ -1286,6 +1134,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 \ @@ -1347,3 +1197,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} 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" 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