diff --git a/.coveragerc-py39 b/.coveragerc-py39 deleted file mode 100644 index 9a54d53ac..000000000 --- a/.coveragerc-py39 +++ /dev/null @@ -1,35 +0,0 @@ -[run] -; This flag writes per-process coverage data files so subprocess coverage -; can be combined with the main test process by pytest-cov. Works with COVERAGE_PROCESS_START in -; tox.ini env variable -; see: https://coverage.readthedocs.io/en/6.5.0/cmd.html#combining-data-files-coverage-combine -parallel = true - -[paths] -; Normalize installed package paths back to source tree so coverage data -; from different tox envs can be combined into a single report -source = - aws-opentelemetry-distro/src/amazon - .tox/3.*/lib/python*/site-packages/amazon - */site-packages/amazon - -[report] -include_namespace_packages = true -fail_under = 95.00 -precision = 2 -; Exclude framework instrumentation not installed on 3.9, -; test files that share the amazon namespace, and pip build artifacts -; so only source code is reported -omit = - */instrumentation/crewai/* - */instrumentation/llama_index/* - */instrumentation/langchain/* - */instrumentation/mcp/* - */instrumentation/openai_agents/* - */tests/* - */pip-build-env-*/* - ; Dynamic Instrumentation line-breakpoint engines are version-exclusive (bytecode for - ; 3.9-3.11, sys.monitoring for 3.12+). Excluded from the coverage gate; each is unit-tested - ; on its native version and both are validated by the DI contract tests. - */distro/debugger/instrumentation_engine/_bytecode_injection_engine.py - */distro/debugger/instrumentation_engine/_sys_monitoring_engine.py diff --git a/.github/actions/set_up/action.yml b/.github/actions/set_up/action.yml index 0580407e2..18ae802e9 100644 --- a/.github/actions/set_up/action.yml +++ b/.github/actions/set_up/action.yml @@ -55,9 +55,7 @@ runs: shell: bash run: | pip install coverage - if [ "${{ inputs.python_version }}" = "3.9" ]; then - RCFILE=.coveragerc-py39 - elif [ "${{ inputs.python_version }}" = "3.14" ]; then + if [ "${{ inputs.python_version }}" = "3.14" ]; then RCFILE=.coveragerc-py314 else RCFILE=.coveragerc diff --git a/.github/workflows/application-signals-e2e-test.yml b/.github/workflows/application-signals-e2e-test.yml index fce880f91..0d1a85b5e 100644 --- a/.github/workflows/application-signals-e2e-test.yml +++ b/.github/workflows/application-signals-e2e-test.yml @@ -46,17 +46,6 @@ jobs: # DEFAULT SETTING: {Python Version}, EC2, AMD64, AL2 # - default-py39-amd64: - needs: [ upload-main-build ] - uses: aws-observability/aws-application-signals-test-framework/.github/workflows/python-ec2-default-test.yml@main - secrets: inherit - with: - aws-region: us-east-1 - caller-workflow-name: 'main-build' - python-version: '3.9' - cpu-architecture: 'x86_64' - staging-wheel-name: ${{ inputs.staging-wheel-name }} - default-py310-amd64: needs: [ upload-main-build ] uses: aws-observability/aws-application-signals-test-framework/.github/workflows/python-ec2-default-test.yml@main @@ -186,17 +175,17 @@ jobs: # # PACKAGED DISTRIBUTION PLATFORM COVERAGE - # DEFAULT SETTING: Python 3.9, {Platform}, AMD64, AL2 + # DEFAULT SETTING: Python 3.10, {Platform}, AMD64, AL2 # - asg-py39-amd64: + asg-py310-amd64: needs: [ upload-main-build ] uses: aws-observability/aws-application-signals-test-framework/.github/workflows/python-ec2-asg-test.yml@main secrets: inherit with: aws-region: us-east-1 caller-workflow-name: 'main-build' - python-version: '3.9' + python-version: '3.10' staging-wheel-name: ${{ inputs.staging-wheel-name }} # @@ -225,17 +214,17 @@ jobs: # # CPU ARCHITECTURE COVERAGE - # DEFAULT SETTING: Python 3.9, EC2, {CPU Architecture}, AL2 + # DEFAULT SETTING: Python 3.10, EC2, {CPU Architecture}, AL2 # - default-py39-arm64: + default-py310-arm64: needs: [ upload-main-build ] uses: aws-observability/aws-application-signals-test-framework/.github/workflows/python-ec2-default-test.yml@main secrets: inherit with: aws-region: us-east-1 caller-workflow-name: 'main-build' - python-version: '3.9' + python-version: '3.10' cpu-architecture: 'arm64' staging-wheel-name: ${{ inputs.staging-wheel-name }} diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index ec0098592..ef25f6fb3 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -127,7 +127,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - name: Checkout Repo @ SHA - ${{ github.sha }} uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 diff --git a/.github/workflows/run-instrumentation-tests.yml b/.github/workflows/run-instrumentation-tests.yml index 6b06e3d00..82c9eb28c 100644 --- a/.github/workflows/run-instrumentation-tests.yml +++ b/.github/workflows/run-instrumentation-tests.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] tox-env: - test-aws-opentelemetry-distro-langchain - test-aws-opentelemetry-distro-crewai diff --git a/CHANGELOG.md b/CHANGELOG.md index 02ae299c2..ecba70407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ If your change does not need a CHANGELOG entry, add the "skip changelog" label t ## Unreleased +- Nightly dependency update: OpenTelemetry 1.42.1/0.63b1 + ([#762](https://github.com/aws-observability/aws-otel-python-instrumentation/pull/762)) - feat(agent-observability): add `AWS_AGENTIC_INSTRUMENTATION` (`auto`/`enabled`/`disabled`, case-insensitive) as an escape hatch over auto-detection when `AGENT_OBSERVABILITY_ENABLED=true`; the switch only governs AWS native instrumentors and never disables third-party ones ([#769](https://github.com/aws-observability/aws-otel-python-instrumentation/pull/769)) - fix(otlp-aws-exporter): avoid `RecursionError` when `pip_system_certs` replaces `ssl.SSLContext` (truststore injection) by rebinding stale `botocore`/`urllib3` SSL context references and caching credentials in `AwsAuthSession` diff --git a/README.md b/README.md index 51ca80e5e..a34d4b890 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This project is licensed under the Apache-2.0 License. ## Notices ### Python Version Support -This project ensures compatibility with the following supported Python versions: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 +This project ensures compatibility with the following supported Python versions: 3.10, 3.11, 3.12, 3.13, 3.14 ### Note on Amazon CloudWatch Application Signals [Amazon CloudWatch Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Monitoring-Sections.html) components are designed to seamlessly work with all library instrumentations offered by [OpenTelemetry Python auto-instrumentation](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/instrumentation/README.md). While upstream OpenTelemetry Python instrumentations are in beta, Application Signals components are stable, production ready and have also been tested for popular libraries/frameworks such as [Django, Boto3, and others](https://github.com/aws-observability/aws-otel-python-instrumentation/tree/main/contract-tests/images/applications). We will prioritize backward compatibility for Application Signals components, striving to ensure that they remain functional even in the face of potential breaking changes introduced by OpenTelemetry upstream libraries. Please [raise an issue](https://github.com/aws-observability/aws-otel-python-instrumentation/blob/main/CONTRIBUTING.md#reporting-bugsfeature-requests) if you notice Application Signals doesn't work for a particular OpenTelemetry supported library. diff --git a/aws-opentelemetry-distro/pyproject.toml b/aws-opentelemetry-distro/pyproject.toml index 06171881d..c6d66769f 100644 --- a/aws-opentelemetry-distro/pyproject.toml +++ b/aws-opentelemetry-distro/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "AWS OpenTelemetry Python Distro" readme = "README.rst" license = {text = "Apache-2.0"} -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "Amazon Web Services" }, ] @@ -18,72 +18,71 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api == 1.40.0", - "opentelemetry-sdk == 1.40.0", - "opentelemetry-exporter-otlp-proto-grpc == 1.40.0", - "opentelemetry-exporter-otlp-proto-http == 1.40.0", - "opentelemetry-propagator-b3 == 1.40.0", - "opentelemetry-propagator-jaeger == 1.40.0", - "opentelemetry-exporter-otlp-proto-common == 1.40.0", + "opentelemetry-api == 1.42.1", + "opentelemetry-sdk == 1.42.1", + "opentelemetry-exporter-otlp-proto-grpc == 1.42.1", + "opentelemetry-exporter-otlp-proto-http == 1.42.1", + "opentelemetry-propagator-b3 == 1.42.1", + "opentelemetry-propagator-jaeger == 1.42.1", + "opentelemetry-exporter-otlp-proto-common == 1.42.1", "opentelemetry-sdk-extension-aws == 2.1.0", "opentelemetry-propagator-aws-xray == 1.0.2", - "opentelemetry-distro == 0.61b0", - "opentelemetry-processor-baggage == 0.61b0", - "opentelemetry-propagator-ot-trace == 0.61b0", - "opentelemetry-instrumentation == 0.61b0", - "opentelemetry-instrumentation-aws-lambda == 0.61b0", - "opentelemetry-instrumentation-aio-pika == 0.61b0", - "opentelemetry-instrumentation-aiohttp-client == 0.61b0", - "opentelemetry-instrumentation-aiokafka == 0.61b0", - "opentelemetry-instrumentation-aiopg == 0.61b0", - "opentelemetry-instrumentation-asgi == 0.61b0", - "opentelemetry-instrumentation-asyncpg == 0.61b0", - "opentelemetry-instrumentation-boto == 0.61b0", - "opentelemetry-instrumentation-boto3sqs == 0.61b0", - "opentelemetry-instrumentation-botocore == 0.61b0", - "opentelemetry-instrumentation-celery == 0.61b0", - "opentelemetry-instrumentation-confluent-kafka == 0.61b0", - "opentelemetry-instrumentation-dbapi == 0.61b0", - "opentelemetry-instrumentation-django == 0.61b0", - "opentelemetry-instrumentation-elasticsearch == 0.61b0", - "opentelemetry-instrumentation-falcon == 0.61b0", - "opentelemetry-instrumentation-fastapi == 0.61b0", - "opentelemetry-instrumentation-flask == 0.61b0", - "opentelemetry-instrumentation-grpc == 0.61b0", - "opentelemetry-instrumentation-httpx == 0.61b0", - "opentelemetry-instrumentation-jinja2 == 0.61b0", - "opentelemetry-instrumentation-kafka-python == 0.61b0", - "opentelemetry-instrumentation-logging == 0.61b0", - "opentelemetry-instrumentation-mysql == 0.61b0", - "opentelemetry-instrumentation-mysqlclient == 0.61b0", - "opentelemetry-instrumentation-pika == 0.61b0", - "opentelemetry-instrumentation-psycopg2 == 0.61b0", - "opentelemetry-instrumentation-pymemcache == 0.61b0", - "opentelemetry-instrumentation-pymongo == 0.61b0", - "opentelemetry-instrumentation-pymysql == 0.61b0", - "opentelemetry-instrumentation-pyramid == 0.61b0", - "opentelemetry-instrumentation-redis == 0.61b0", - "opentelemetry-instrumentation-remoulade == 0.61b0", - "opentelemetry-instrumentation-requests == 0.61b0", - "opentelemetry-instrumentation-sqlalchemy == 0.61b0", - "opentelemetry-instrumentation-sqlite3 == 0.61b0", - "opentelemetry-instrumentation-starlette == 0.61b0", - "opentelemetry-instrumentation-system-metrics == 0.61b0", - "opentelemetry-instrumentation-threading == 0.61b0", - "opentelemetry-instrumentation-tornado == 0.61b0", - "opentelemetry-instrumentation-tortoiseorm == 0.61b0", - "opentelemetry-instrumentation-urllib == 0.61b0", - "opentelemetry-instrumentation-urllib3 == 0.61b0", - "opentelemetry-instrumentation-wsgi == 0.61b0", - "opentelemetry-instrumentation-cassandra == 0.61b0", + "opentelemetry-distro == 0.63b1", + "opentelemetry-processor-baggage == 0.63b1", + "opentelemetry-propagator-ot-trace == 0.63b1", + "opentelemetry-instrumentation == 0.63b1", + "opentelemetry-instrumentation-aws-lambda == 0.63b1", + "opentelemetry-instrumentation-aio-pika == 0.63b1", + "opentelemetry-instrumentation-aiohttp-client == 0.63b1", + "opentelemetry-instrumentation-aiokafka == 0.63b1", + "opentelemetry-instrumentation-aiopg == 0.63b1", + "opentelemetry-instrumentation-asgi == 0.63b1", + "opentelemetry-instrumentation-asyncpg == 0.63b1", + "opentelemetry-instrumentation-boto3sqs == 0.63b1", + "opentelemetry-instrumentation-botocore == 0.63b1", + "opentelemetry-instrumentation-celery == 0.63b1", + "opentelemetry-instrumentation-confluent-kafka == 0.63b1", + "opentelemetry-instrumentation-dbapi == 0.63b1", + "opentelemetry-instrumentation-django == 0.63b1", + "opentelemetry-instrumentation-elasticsearch == 0.63b1", + "opentelemetry-instrumentation-falcon == 0.63b1", + "opentelemetry-instrumentation-fastapi == 0.63b1", + "opentelemetry-instrumentation-flask == 0.63b1", + "opentelemetry-instrumentation-grpc == 0.63b1", + "opentelemetry-instrumentation-httpx == 0.63b1", + "opentelemetry-instrumentation-jinja2 == 0.63b1", + "opentelemetry-instrumentation-kafka-python == 0.63b1", + "opentelemetry-instrumentation-logging == 0.63b1", + "opentelemetry-instrumentation-mysql == 0.63b1", + "opentelemetry-instrumentation-mysqlclient == 0.63b1", + "opentelemetry-instrumentation-pika == 0.63b1", + "opentelemetry-instrumentation-psycopg2 == 0.63b1", + "opentelemetry-instrumentation-pymemcache == 0.63b1", + "opentelemetry-instrumentation-pymongo == 0.63b1", + "opentelemetry-instrumentation-pymysql == 0.63b1", + "opentelemetry-instrumentation-pyramid == 0.63b1", + "opentelemetry-instrumentation-redis == 0.63b1", + "opentelemetry-instrumentation-remoulade == 0.63b1", + "opentelemetry-instrumentation-requests == 0.63b1", + "opentelemetry-instrumentation-sqlalchemy == 0.63b1", + "opentelemetry-instrumentation-sqlite3 == 0.63b1", + "opentelemetry-instrumentation-starlette == 0.63b1", + "opentelemetry-instrumentation-system-metrics == 0.63b1", + "opentelemetry-instrumentation-threading == 0.63b1", + "opentelemetry-instrumentation-tornado == 0.63b1", + "opentelemetry-instrumentation-tortoiseorm == 0.63b1", + "opentelemetry-instrumentation-urllib == 0.63b1", + "opentelemetry-instrumentation-urllib3 == 0.63b1", + "opentelemetry-instrumentation-wsgi == 0.63b1", + "opentelemetry-instrumentation-cassandra == 0.63b1", "opentelemetry-instrumentation-openai-agents-v2 == 0.1.0", "cachetools == 6.2.4", "urllib3 >= 2.7.0; python_version >= '3.10'", @@ -93,9 +92,9 @@ dependencies = [ # (debugger/_data_models.py). Required on all supported Python versions, hence a core dependency. "python-dateutil >= 2.7.0", # Used by Dynamic Instrumentation's bytecode-injection engine for line-level instrumentation on - # Python 3.9-3.11 (3.12+ uses the built-in sys.monitoring instead, so the marker excludes it there). + # Python 3.10-3.11 (3.12+ uses the built-in sys.monitoring instead, so the marker excludes it there). # A core dependency so `pip install aws-opentelemetry-distro` gives a fully working feature with no extras. - "bytecode; python_version >= '3.9' and python_version < '3.12'", + "bytecode; python_version >= '3.10' and python_version < '3.12'", ] [project.optional-dependencies] diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_utils.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_utils.py index aa54ef117..b2e7b0ea2 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_utils.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_utils.py @@ -52,7 +52,7 @@ def should_add_application_signals_dimensions() -> bool: IS_BOTOCORE_INSTALLED: bool = is_installed("botocore") # The 'bytecode' package is an optional dependency (the 'debugger' extra), installed only on -# Python 3.9-3.11. Dynamic Instrumentation's bytecode-injection engine guards on this flag. +# Python 3.10-3.11. Dynamic Instrumentation's bytecode-injection engine guards on this flag. IS_BYTECODE_INSTALLED: bool = is_installed("bytecode") diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_opentelemetry_configurator.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_opentelemetry_configurator.py index 38561802a..c4f24d409 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_opentelemetry_configurator.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_opentelemetry_configurator.py @@ -7,12 +7,12 @@ import logging import os import re +from importlib.metadata import version from logging import Logger, getLogger from pathlib import Path from typing import ClassVar, Dict, List, NamedTuple, Optional, Type, Union import yaml -from importlib_metadata import version from typing_extensions import override from amazon.opentelemetry.distro._aws_attribute_keys import AWS_LOCAL_SERVICE, AWS_SERVICE_TYPE diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/code_correlation/internal/3rd.txt b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/code_correlation/internal/3rd.txt index 51d3e94b2..59528329f 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/code_correlation/internal/3rd.txt +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/code_correlation/internal/3rd.txt @@ -3596,7 +3596,6 @@ autoevals keyrings-codeartifact lpips ldapdomaindump -opentelemetry-instrumentation-boto suds-py3 appengine-python-standard litellm-proxy-extras diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_bytecode_injection_engine.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_bytecode_injection_engine.py index 2f716aed2..bc5e7ca3a 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_bytecode_injection_engine.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_bytecode_injection_engine.py @@ -5,7 +5,7 @@ Bytecode injection engine for live debugger. This module handles the injection of breakpoint calls into Python functions -using bytecode injection for Python 3.9-3.11. +using bytecode injection for Python 3.10-3.11. """ import inspect @@ -71,7 +71,7 @@ class InjectionState: class BytecodeInjectionEngine(InstrumentationEngine): """ - Bytecode injection engine for line-level debugging on Python 3.9-3.11. + Bytecode injection engine for line-level debugging on Python 3.10-3.11. Safety guarantees: - Never crashes the application (comprehensive exception handling) @@ -95,7 +95,7 @@ def __init__(self): if not IS_BYTECODE_INSTALLED: logger.warning( "bytecode library not available. " - "Debugger will not function on Python 3.9-3.11. " + "Debugger will not function on Python 3.10-3.11. " "Install with: pip install bytecode" ) @@ -123,8 +123,8 @@ def initialize(self, hit_count_callback=None) -> None: @staticmethod def supports_runtime() -> bool: - """Check if bytecode injection is supported (Python 3.9-3.11).""" - return (3, 9) <= sys.version_info < (3, 12) and IS_BYTECODE_INSTALLED + """Check if bytecode injection is supported (Python 3.10-3.11).""" + return (3, 10) <= sys.version_info < (3, 12) and IS_BYTECODE_INSTALLED def enable_breakpoints_for_function( self, @@ -498,8 +498,8 @@ def _create_breakpoint_instructions(self, function_key: str, line_number: int) - try: if sys.version_info >= (3, 11): return self._create_breakpoint_instructions_py311(function_key, line_number) - if sys.version_info >= (3, 9): - return self._create_breakpoint_instructions_py39_py310(function_key, line_number) + if sys.version_info >= (3, 10): + return self._create_breakpoint_instructions_py310(function_key, line_number) logger.error("Unsupported Python version: %s", sys.version_info) return None except Exception as exc: # pylint: disable=broad-exception-caught @@ -541,14 +541,14 @@ def _create_breakpoint_instructions_py311(function_key: str, line_number: int) - ] @staticmethod - def _create_breakpoint_instructions_py39_py310(function_key: str, line_number: int) -> list: + def _create_breakpoint_instructions_py310(function_key: str, line_number: int) -> list: """ - Create Python 3.9/3.10-specific breakpoint instructions. + Create Python 3.10-specific breakpoint instructions. Generates bytecode that calls: _breakpoint_handler(function_key, line_number, locals()) - Python 3.9/3.10 calling convention: + Python 3.10 calling convention: - LOAD_GLOBAL (load _breakpoint_handler) - LOAD_CONST (load arguments) - LOAD_GLOBAL + CALL_FUNCTION (call locals()) diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_instrumentation_engine.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_instrumentation_engine.py index b26622b12..beb8cab71 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_instrumentation_engine.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_engine/_instrumentation_engine.py @@ -6,7 +6,7 @@ This module provides a common interface for different instrumentation mechanisms: - SysMonitoringEngine (Python 3.12+) -- BytecodeInjectionEngine (Python 3.9-3.11) +- BytecodeInjectionEngine (Python 3.10-3.11) """ from abc import ABC, abstractmethod diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_manager.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_manager.py index 940db97b5..d6654cbed 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_manager.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/debugger/instrumentation_manager.py @@ -127,8 +127,8 @@ def _select_engine(self) -> Optional[InstrumentationEngine]: # pragma: no cover except Exception as exception: # pylint: disable=broad-exception-caught logger.error("Failed to initialize SysMonitoringEngine: %s", exception, exc_info=True) - # Python 3.9-3.11 - Use BytecodeInjectionEngine - elif sys.version_info >= (3, 9): + # Python 3.10-3.11 - Use BytecodeInjectionEngine + elif sys.version_info >= (3, 10): try: # pylint: disable=import-outside-toplevel from amazon.opentelemetry.distro.debugger.instrumentation_engine._bytecode_injection_engine import ( @@ -146,11 +146,11 @@ def _select_engine(self) -> Optional[InstrumentationEngine]: # pragma: no cover except Exception as exception: # pylint: disable=broad-exception-caught logger.error("Failed to initialize BytecodeInjectionEngine: %s", exception, exc_info=True) - # Python < 3.9 - Not supported + # Python < 3.10 - Not supported else: logger.warning( "Python %d.%d is not supported for line breakpoints. " - "Supported versions: 3.9-3.12+. Function wrapping will still work, but line breakpoints will not.", + "Supported versions: 3.10-3.12+. Function wrapping will still work, but line breakpoints will not.", sys.version_info.major, sys.version_info.minor, ) diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_botocore_patches.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_botocore_patches.py index c1b2d0b9f..3985c20d2 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_botocore_patches.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_botocore_patches.py @@ -26,9 +26,8 @@ BotocoreInstrumentor, _apply_response_attributes, _determine_call_context, - _safe_invoke, ) -from opentelemetry.instrumentation.botocore.extensions import _KNOWN_EXTENSIONS, _find_extension +from opentelemetry.instrumentation.botocore.extensions import _BOTOCORE_EXTENSIONS from opentelemetry.instrumentation.botocore.extensions.dynamodb import _DynamoDbExtension from opentelemetry.instrumentation.botocore.extensions.lmbd import _LambdaExtension from opentelemetry.instrumentation.botocore.extensions.sqs import _SqsExtension @@ -38,7 +37,7 @@ _BotocoreInstrumentorContext, _BotoResultT, ) -from opentelemetry.instrumentation.botocore.utils import get_server_attributes +from opentelemetry.instrumentation.botocore.utils import _safe_invoke, get_server_attributes from opentelemetry.instrumentation.utils import is_instrumentation_enabled, suppress_http_instrumentation from opentelemetry.propagate import get_global_textmap from opentelemetry.semconv._incubating.attributes.aws_attributes import ( @@ -135,7 +134,7 @@ def _apply_botocore_kinesis_patch() -> None: the `aws.kinesis.stream.name` attribute, to be used to generate RemoteTarget and achieve parity with the Java instrumentation. """ - _KNOWN_EXTENSIONS["kinesis"] = _lazy_load(".", "_KinesisExtension") + _BOTOCORE_EXTENSIONS["kinesis"] = _lazy_load(".", "_KinesisExtension") def _apply_botocore_s3_patch() -> None: @@ -147,7 +146,7 @@ def _apply_botocore_s3_patch() -> None: Callout that AWS_S3_BUCKET is in the AWS Semantic Conventions, and is simply not implemented in Python instrumentation. """ - _KNOWN_EXTENSIONS["s3"] = _lazy_load(".", "_S3Extension") + _BOTOCORE_EXTENSIONS["s3"] = _lazy_load(".", "_S3Extension") def _apply_botocore_sqs_patch() -> None: @@ -190,11 +189,11 @@ def _apply_botocore_bedrock_patch() -> None: Specifically, we are adding logic to add the AWS_BEDROCK attributes referenced in _aws_attribute_keys. Note: Bedrock Runtime uses the upstream extension directly. """ - _KNOWN_EXTENSIONS["bedrock"] = _lazy_load(".", "_BedrockExtension") - _KNOWN_EXTENSIONS["bedrock-agent"] = _lazy_load(".", "_BedrockAgentExtension") - _KNOWN_EXTENSIONS["bedrock-agent-runtime"] = _lazy_load(".", "_BedrockAgentRuntimeExtension") - _KNOWN_EXTENSIONS["bedrock-agentcore"] = _lazy_load(".._bedrock_agentcore_patches", "_BedrockAgentCoreExtension") - _KNOWN_EXTENSIONS["bedrock-agentcore-control"] = _lazy_load( + _BOTOCORE_EXTENSIONS["bedrock"] = _lazy_load(".", "_BedrockExtension") + _BOTOCORE_EXTENSIONS["bedrock-agent"] = _lazy_load(".", "_BedrockAgentExtension") + _BOTOCORE_EXTENSIONS["bedrock-agent-runtime"] = _lazy_load(".", "_BedrockAgentRuntimeExtension") + _BOTOCORE_EXTENSIONS["bedrock-agentcore"] = _lazy_load(".._bedrock_agentcore_patches", "_BedrockAgentCoreExtension") + _BOTOCORE_EXTENSIONS["bedrock-agentcore-control"] = _lazy_load( ".._bedrock_agentcore_patches", "_BedrockAgentCoreExtension" ) @@ -230,13 +229,13 @@ def patched_api_call(self, original_func, instance, args, kwargs): - aws.auth.account.access_key - aws.auth.region - Note: Current implementation duplicates upstream code in v1.33.x-0.54bx. Future improvements should: + Note: Current implementation duplicates upstream code in v1.42.x-0.63bx. Future improvements should: 1. Propose refactoring upstream _patched_api_call into smaller components 2. Apply targeted patches to these components to reduce code duplication Reference: https://github.com/open-telemetry/opentelemetry-python-contrib/blob/ - release/v1.33.x-0.54bx/instrumentation/opentelemetry-instrumentation-botocore/src/ - opentelemetry/instrumentation/botocore/__init__.py#L263 + release/v1.42.x-0.63bx/instrumentation/opentelemetry-instrumentation-botocore/src/ + opentelemetry/instrumentation/botocore/__init__.py """ if not is_instrumentation_enabled(): return original_func(*args, **kwargs) @@ -245,7 +244,7 @@ def patched_api_call(self, original_func, instance, args, kwargs): if call_context is None: return original_func(*args, **kwargs) - extension = _find_extension(call_context) + extension = self.extension_registry.get_extension(call_context) if not extension.should_trace_service_call(): return original_func(*args, **kwargs) @@ -268,11 +267,10 @@ def patched_api_call(self, original_func, instance, args, kwargs): _safe_invoke(extension.extract_attributes, attributes) end_span_on_exit = extension.should_end_span_on_exit() - tracer = self._get_tracer(extension) - meter = self._get_meter(extension) - metrics = self._get_metrics(extension, meter) + tracer = self.extension_registry.get_tracer(extension) + metrics = self.extension_registry.get_metrics(extension) instrumentor_ctx = _BotocoreInstrumentorContext( - logger=self._get_logger(extension), + logger=self.extension_registry.get_logger(extension), metrics=metrics, ) with tracer.start_as_current_span( diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_starlette_patches.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_starlette_patches.py index bf6c5f58d..ac35d8b2c 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_starlette_patches.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_starlette_patches.py @@ -16,7 +16,6 @@ def _apply_starlette_instrumentation_patches() -> None: try: # pylint: disable=import-outside-toplevel from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware - from opentelemetry.instrumentation.utils import is_http_instrumentation_enabled # pylint: disable=line-too-long # Patch to exclude http receive/send ASGI event spans from Bedrock AgentCore, @@ -37,17 +36,6 @@ def patched_init(self, app, **kwargs): OpenTelemetryMiddleware.__init__ = patched_init - # TODO: Remove this patch once upstream PR is merged: - # https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4375 - original_call = OpenTelemetryMiddleware.__call__ - - async def patched_call(self, scope, receive, send): - if not is_http_instrumentation_enabled(): - return await self.app(scope, receive, send) - return await original_call(self, scope, receive, send) - - OpenTelemetryMiddleware.__call__ = patched_call - _logger.debug("Successfully patched Starlette ASGI middleware") except Exception as exc: # pylint: disable=broad-except _logger.warning("Failed to apply Starlette instrumentation patches: %s", exc) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/code_correlation/internal/test_packages_resolver.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/code_correlation/internal/test_packages_resolver.py index 4b897eb44..ae3dbbf27 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/code_correlation/internal/test_packages_resolver.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/code_correlation/internal/test_packages_resolver.py @@ -218,7 +218,7 @@ def test_determine_effective_root_package_with_init(self): with patch("pathlib.Path.is_dir", return_value=True), patch("pathlib.Path.exists", return_value=True): relative_path = Path("mypackage/submodule.py") - parent_path = Path("/usr/lib/python3.9/site-packages") + parent_path = Path("/usr/lib/python3.10/site-packages") result = _determine_effective_root(relative_path, parent_path) self.assertEqual(result, "mypackage") @@ -227,7 +227,7 @@ def test_determine_effective_root_no_init(self): """Test determining root for module without __init__.py.""" with patch("pathlib.Path.is_dir", return_value=False): relative_path = Path("module/file.py") - parent_path = Path("/usr/lib/python3.9/site-packages") + parent_path = Path("/usr/lib/python3.10/site-packages") result = _determine_effective_root(relative_path, parent_path) self.assertEqual(result, "module/file.py") @@ -237,7 +237,7 @@ def test_determine_effective_root_directory_no_init(self): with patch("pathlib.Path.is_dir", return_value=True), patch("pathlib.Path.exists", return_value=False): relative_path = Path("namespace/subpackage.py") - parent_path = Path("/usr/lib/python3.9/site-packages") + parent_path = Path("/usr/lib/python3.10/site-packages") result = _determine_effective_root(relative_path, parent_path) self.assertEqual(result, "namespace/subpackage.py") @@ -289,7 +289,7 @@ class TestExtractRootModuleName(TestCase): @patch("amazon.opentelemetry.distro.code_correlation.internal.packages_resolver._PURELIB_PATH") def test_extract_root_module_name_purelib(self, mock_purelib): """Test extracting root module name from purelib path.""" - mock_purelib.return_value = Path("/usr/lib/python3.9/site-packages") + mock_purelib.return_value = Path("/usr/lib/python3.10/site-packages") with patch.object(Path, "resolve") as mock_resolve, patch.object( Path, "relative_to" @@ -297,11 +297,11 @@ def test_extract_root_module_name_purelib(self, mock_purelib): "amazon.opentelemetry.distro.code_correlation.internal.packages_resolver._determine_effective_root" ) as mock_determine: - mock_resolve.return_value = Path("/usr/lib/python3.9/site-packages/mypackage/module.py") + mock_resolve.return_value = Path("/usr/lib/python3.10/site-packages/mypackage/module.py") mock_relative_to.return_value = Path("mypackage/module.py") mock_determine.return_value = "mypackage" - file_path = Path("/usr/lib/python3.9/site-packages/mypackage/module.py") + file_path = Path("/usr/lib/python3.10/site-packages/mypackage/module.py") result = _extract_root_module_name(file_path) self.assertEqual(result, "mypackage") @@ -611,7 +611,7 @@ def test_is_user_code_stdlib(self, mock_is_third_party, mock_is_stdlib): mock_is_stdlib.return_value = True mock_is_third_party.return_value = False - result = is_user_code("/usr/lib/python3.9/os.py") + result = is_user_code("/usr/lib/python3.10/os.py") self.assertFalse(result) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/debugger/instrumentation_engine/test_bytecode_injection_engine.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/debugger/instrumentation_engine/test_bytecode_injection_engine.py index a679c1f1e..68292b182 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/debugger/instrumentation_engine/test_bytecode_injection_engine.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/debugger/instrumentation_engine/test_bytecode_injection_engine.py @@ -12,7 +12,7 @@ from amazon.opentelemetry.distro.debugger.instrumentation_engine import _bytecode_injection_engine -@unittest.skipIf(not (3, 9) <= sys.version_info < (3, 12), "BytecodeInjectionEngine requires Python 3.9-3.11") +@unittest.skipIf(not (3, 10) <= sys.version_info < (3, 12), "BytecodeInjectionEngine requires Python 3.10-3.11") class TestBytecodeInjectionEngine(InstrumentationEngineTestBase): """Tests for BytecodeInjectionEngine.""" diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_instrumentation_patch.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_instrumentation_patch.py index 46798dbbc..49bf411a5 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_instrumentation_patch.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_instrumentation_patch.py @@ -34,7 +34,7 @@ GEN_AI_RUNTIME_ID, ) from opentelemetry.instrumentation.botocore import BotocoreInstrumentor -from opentelemetry.instrumentation.botocore.extensions import _KNOWN_EXTENSIONS, bedrock_utils +from opentelemetry.instrumentation.botocore.extensions import _BOTOCORE_EXTENSIONS, bedrock_utils from opentelemetry.propagate import get_global_textmap from opentelemetry.semconv._incubating.attributes.aws_attributes import ( AWS_BEDROCK_GUARDRAIL_ID, @@ -178,55 +178,58 @@ def _run_patch_mechanism_tests(self): def _test_unpatched_botocore_instrumentation(self): # Kinesis - self.assertFalse("kinesis" in _KNOWN_EXTENSIONS, "Upstream has added a Kinesis extension") + self.assertFalse("kinesis" in _BOTOCORE_EXTENSIONS, "Upstream has added a Kinesis extension") # S3 - self.assertFalse("s3" in _KNOWN_EXTENSIONS, "Upstream has added a S3 extension") + self.assertFalse("s3" in _BOTOCORE_EXTENSIONS, "Upstream has added a S3 extension") # SQS - self.assertTrue("sqs" in _KNOWN_EXTENSIONS, "Upstream has removed the SQS extension") + self.assertTrue("sqs" in _BOTOCORE_EXTENSIONS, "Upstream has removed the SQS extension") # Bedrock - self.assertFalse("bedrock" in _KNOWN_EXTENSIONS, "Upstream has added a Bedrock extension") + self.assertFalse("bedrock" in _BOTOCORE_EXTENSIONS, "Upstream has added a Bedrock extension") # Bedrock Agent - self.assertFalse("bedrock-agent" in _KNOWN_EXTENSIONS, "Upstream has added a Bedrock Agent extension") + self.assertFalse("bedrock-agent" in _BOTOCORE_EXTENSIONS, "Upstream has added a Bedrock Agent extension") # Bedrock Agent Runtime self.assertFalse( - "bedrock-agent-runtime" in _KNOWN_EXTENSIONS, "Upstream has added a Bedrock Agent Runtime extension" + "bedrock-agent-runtime" in _BOTOCORE_EXTENSIONS, "Upstream has added a Bedrock Agent Runtime extension" ) # Bedrock AgentCore - self.assertFalse("bedrock-agentcore" in _KNOWN_EXTENSIONS, "Upstream has added a Bedrock AgentCore extension") + self.assertFalse( + "bedrock-agentcore" in _BOTOCORE_EXTENSIONS, "Upstream has added a Bedrock AgentCore extension" + ) # Bedrock AgentCore Control self.assertFalse( - "bedrock-agentcore-control" in _KNOWN_EXTENSIONS, "Upstream has added a Bedrock AgentCore Control extension" + "bedrock-agentcore-control" in _BOTOCORE_EXTENSIONS, + "Upstream has added a Bedrock AgentCore Control extension", ) # BedrockRuntime - self.assertTrue("bedrock-runtime" in _KNOWN_EXTENSIONS, "Upstream has added a bedrock-runtime extension") + self.assertTrue("bedrock-runtime" in _BOTOCORE_EXTENSIONS, "Upstream has added a bedrock-runtime extension") # SecretsManager - self.assertTrue("secretsmanager" in _KNOWN_EXTENSIONS, "Upstream has removed the SecretsManager extension") + self.assertTrue("secretsmanager" in _BOTOCORE_EXTENSIONS, "Upstream has removed the SecretsManager extension") # SNS - self.assertTrue("sns" in _KNOWN_EXTENSIONS, "Upstream has removed the SNS extension") + self.assertTrue("sns" in _BOTOCORE_EXTENSIONS, "Upstream has removed the SNS extension") # StepFunctions - self.assertTrue("stepfunctions" in _KNOWN_EXTENSIONS, "Upstream has removed the StepFunctions extension") + self.assertTrue("stepfunctions" in _BOTOCORE_EXTENSIONS, "Upstream has removed the StepFunctions extension") # Lambda - self.assertTrue("lambda" in _KNOWN_EXTENSIONS, "Upstream has removed the Lambda extension") + self.assertTrue("lambda" in _BOTOCORE_EXTENSIONS, "Upstream has removed the Lambda extension") # DynamoDB - self.assertTrue("dynamodb" in _KNOWN_EXTENSIONS, "Upstream has removed a DynamoDB extension") + self.assertTrue("dynamodb" in _BOTOCORE_EXTENSIONS, "Upstream has removed a DynamoDB extension") # pylint: disable=too-many-statements, too-many-locals def _test_patched_botocore_instrumentation(self): # Kinesis - self.assertTrue("kinesis" in _KNOWN_EXTENSIONS) + self.assertTrue("kinesis" in _BOTOCORE_EXTENSIONS) kinesis_attributes: Dict[str, str] = _do_extract_kinesis_attributes() self.assertTrue(AWS_KINESIS_STREAM_NAME in kinesis_attributes) self.assertEqual(kinesis_attributes[AWS_KINESIS_STREAM_NAME], _STREAM_NAME) @@ -234,13 +237,13 @@ def _test_patched_botocore_instrumentation(self): self.assertEqual(kinesis_attributes[AWS_KINESIS_STREAM_ARN], _STREAM_ARN) # S3 - self.assertTrue("s3" in _KNOWN_EXTENSIONS) + self.assertTrue("s3" in _BOTOCORE_EXTENSIONS) s3_attributes: Dict[str, str] = _do_extract_s3_attributes() self.assertTrue(AWS_S3_BUCKET in s3_attributes) self.assertEqual(s3_attributes[AWS_S3_BUCKET], _BUCKET_NAME) # SQS - self.assertTrue("sqs" in _KNOWN_EXTENSIONS) + self.assertTrue("sqs" in _BOTOCORE_EXTENSIONS) sqs_attributes: Dict[str, str] = _do_extract_sqs_attributes() self.assertTrue(AWS_SQS_QUEUE_URL in sqs_attributes) self.assertEqual(sqs_attributes[AWS_SQS_QUEUE_URL], _QUEUE_URL) @@ -264,7 +267,7 @@ def _test_patched_botocore_instrumentation(self): self._test_patched_from_converse_with_malformed_response() # Bedrock Agent Runtime - self.assertTrue("bedrock-agent-runtime" in _KNOWN_EXTENSIONS) + self.assertTrue("bedrock-agent-runtime" in _BOTOCORE_EXTENSIONS) bedrock_agent_runtime_attributes: Dict[str, str] = _do_extract_attributes_bedrock("bedrock-agent-runtime") self.assertEqual(len(bedrock_agent_runtime_attributes), 2) self.assertEqual(bedrock_agent_runtime_attributes[AWS_BEDROCK_AGENT_ID], _BEDROCK_AGENT_ID) @@ -273,8 +276,8 @@ def _test_patched_botocore_instrumentation(self): self.assertEqual(len(bedrock_agent_runtime_sucess_attributes), 0) # Bedrock AgentCore - self.assertTrue("bedrock-agentcore" in _KNOWN_EXTENSIONS) - self.assertTrue("bedrock-agentcore-control" in _KNOWN_EXTENSIONS) + self.assertTrue("bedrock-agentcore" in _BOTOCORE_EXTENSIONS) + self.assertTrue("bedrock-agentcore-control" in _BOTOCORE_EXTENSIONS) _do_extract_bedrock_agentcore_attributes, _do_on_success_bedrock_agentcore = _do_bedrock_agentcore_tests() bedrock_agentcore_attributes: Dict[str, str] = _do_extract_bedrock_agentcore_attributes() @@ -314,10 +317,10 @@ def _test_patched_botocore_instrumentation(self): self.assertEqual(name_success_attrs[AWS_AUTH_CREDENTIAL_PROVIDER], _AGENTCORE_CREDENTIAL_PROVIDER_NAME) # BedrockRuntime - self.assertTrue("bedrock-runtime" in _KNOWN_EXTENSIONS) + self.assertTrue("bedrock-runtime" in _BOTOCORE_EXTENSIONS) # SecretsManager - self.assertTrue("secretsmanager" in _KNOWN_EXTENSIONS) + self.assertTrue("secretsmanager" in _BOTOCORE_EXTENSIONS) secretsmanager_attributes: Dict[str, str] = _do_extract_secretsmanager_attributes() self.assertTrue(AWS_SECRETSMANAGER_SECRET_ARN in secretsmanager_attributes) self.assertEqual(secretsmanager_attributes[AWS_SECRETSMANAGER_SECRET_ARN], _SECRET_ARN) @@ -326,13 +329,13 @@ def _test_patched_botocore_instrumentation(self): self.assertEqual(secretsmanager_success_attributes[AWS_SECRETSMANAGER_SECRET_ARN], _SECRET_ARN) # SNS - self.assertTrue("sns" in _KNOWN_EXTENSIONS) + self.assertTrue("sns" in _BOTOCORE_EXTENSIONS) sns_attributes: Dict[str, str] = _do_extract_sns_attributes() self.assertTrue(AWS_SNS_TOPIC_ARN in sns_attributes) self.assertEqual(sns_attributes[AWS_SNS_TOPIC_ARN], _TOPIC_ARN) # StepFunctions - self.assertTrue("stepfunctions" in _KNOWN_EXTENSIONS) + self.assertTrue("stepfunctions" in _BOTOCORE_EXTENSIONS) stepfunctions_attributes: Dict[str, str] = _do_extract_stepfunctions_attributes() self.assertTrue(AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN in stepfunctions_attributes) self.assertEqual(stepfunctions_attributes[AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN], _STATE_MACHINE_ARN) @@ -340,7 +343,7 @@ def _test_patched_botocore_instrumentation(self): self.assertEqual(stepfunctions_attributes[AWS_STEP_FUNCTIONS_ACTIVITY_ARN], _ACTIVITY_ARN) # Lambda - self.assertTrue("lambda" in _KNOWN_EXTENSIONS) + self.assertTrue("lambda" in _BOTOCORE_EXTENSIONS) lambda_attributes: Dict[str, str] = _do_extract_lambda_attributes() self.assertTrue(AWS_LAMBDA_FUNCTION_NAME in lambda_attributes) self.assertEqual(lambda_attributes[AWS_LAMBDA_FUNCTION_NAME], _LAMBDA_FUNCTION_NAME) @@ -348,7 +351,7 @@ def _test_patched_botocore_instrumentation(self): self.assertEqual(lambda_attributes[AWS_LAMBDA_RESOURCE_MAPPING_ID], _LAMBDA_SOURCE_MAPPING_ID) # DynamoDB - self.assertTrue("dynamodb" in _KNOWN_EXTENSIONS) + self.assertTrue("dynamodb" in _BOTOCORE_EXTENSIONS) dynamodb_success_attributes: Dict[str, str] = _do_on_success_dynamodb() self.assertTrue(AWS_DYNAMODB_TABLE_ARN in dynamodb_success_attributes) self.assertEqual(dynamodb_success_attributes[AWS_DYNAMODB_TABLE_ARN], _TABLE_ARN) @@ -388,16 +391,22 @@ def mock_start_span(*args, **kwargs): with patch( "opentelemetry.instrumentation.botocore._determine_call_context", return_value=mock_call_context - ), patch("opentelemetry.instrumentation.botocore._find_extension", return_value=mock_extension), patch( + ), patch( + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_extension", + return_value=mock_extension, + ), patch( "opentelemetry.instrumentation.botocore.is_instrumentation_enabled", return_value=True ), patch( "amazon.opentelemetry.distro.patches._botocore_patches.get_server_attributes", return_value={} ), patch( - "opentelemetry.instrumentation.botocore.get_tracer", return_value=mock_tracer + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_tracer", + return_value=mock_tracer, ), patch( - "opentelemetry.instrumentation.botocore.get_logger", return_value=MagicMock() + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_logger", + return_value=MagicMock(), ), patch( - "opentelemetry.instrumentation.botocore.get_meter", return_value=MagicMock() + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_metrics", + return_value={}, ): instrumentor = BotocoreInstrumentor() instrumentor.instrument() @@ -436,16 +445,22 @@ def mock_start_span(*args, **kwargs): with patch( "opentelemetry.instrumentation.botocore._determine_call_context", return_value=mock_call_context - ), patch("opentelemetry.instrumentation.botocore._find_extension", return_value=mock_extension), patch( + ), patch( + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_extension", + return_value=mock_extension, + ), patch( "opentelemetry.instrumentation.botocore.is_instrumentation_enabled", return_value=True ), patch( "amazon.opentelemetry.distro.patches._botocore_patches.get_server_attributes", return_value={} ), patch( - "opentelemetry.instrumentation.botocore.get_tracer", return_value=mock_tracer + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_tracer", + return_value=mock_tracer, ), patch( - "opentelemetry.instrumentation.botocore.get_logger", return_value=MagicMock() + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_logger", + return_value=MagicMock(), ), patch( - "opentelemetry.instrumentation.botocore.get_meter", return_value=MagicMock() + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_metrics", + return_value={}, ): instrumentor = BotocoreInstrumentor() instrumentor.instrument() @@ -484,16 +499,22 @@ def mock_start_span(*args, **kwargs): with patch( "opentelemetry.instrumentation.botocore._determine_call_context", return_value=mock_call_context - ), patch("opentelemetry.instrumentation.botocore._find_extension", return_value=mock_extension), patch( + ), patch( + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_extension", + return_value=mock_extension, + ), patch( "opentelemetry.instrumentation.botocore.is_instrumentation_enabled", return_value=True ), patch( "amazon.opentelemetry.distro.patches._botocore_patches.get_server_attributes", return_value={} ), patch( - "opentelemetry.instrumentation.botocore.get_tracer", return_value=mock_tracer + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_tracer", + return_value=mock_tracer, ), patch( - "opentelemetry.instrumentation.botocore.get_logger", return_value=MagicMock() + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_logger", + return_value=MagicMock(), ), patch( - "opentelemetry.instrumentation.botocore.get_meter", return_value=MagicMock() + "opentelemetry.instrumentation.botocore.extensions.registry.ExtensionRegistry.get_metrics", + return_value={}, ): instrumentor = BotocoreInstrumentor() instrumentor.instrument() @@ -745,7 +766,7 @@ def _test_process_anthropic_claude_chunk( def _test_patched_bedrock_agent_instrumentation(self): """For bedrock-agent service, both extract_attributes and on_success provides attributes, the attributes depend on the API being invoked.""" - self.assertTrue("bedrock-agent" in _KNOWN_EXTENSIONS) + self.assertTrue("bedrock-agent" in _BOTOCORE_EXTENSIONS) operation_to_expected_attribute = { "CreateAgentActionGroup": (AWS_BEDROCK_AGENT_ID, _BEDROCK_AGENT_ID), "CreateAgentAlias": (AWS_BEDROCK_AGENT_ID, _BEDROCK_AGENT_ID), @@ -1286,7 +1307,7 @@ def _do_extract_attributes(service_name: str, params: Dict[str, Any], operation: if operation: mock_call_context.operation = operation attributes: Dict[str, str] = {} - sqs_extension = _KNOWN_EXTENSIONS[service_name]()(mock_call_context) + sqs_extension = _BOTOCORE_EXTENSIONS[service_name]()(mock_call_context) sqs_extension.extract_attributes(attributes) return attributes @@ -1316,7 +1337,7 @@ def set_side_effect(set_key, set_value): if params: mock_call_context.params = params - extension = _KNOWN_EXTENSIONS[service_name]()(mock_call_context) + extension = _BOTOCORE_EXTENSIONS[service_name]()(mock_call_context) extension.on_success(span_mock, result, mock_instrumentor_context) return span_attributes diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_starlette_patches.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_starlette_patches.py index d90a31457..8181637c6 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_starlette_patches.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_starlette_patches.py @@ -102,7 +102,7 @@ async def simple_asgi(scope, receive, send): } for case, apply_patch, expect_spans in [ - ("unpatched", False, True), + ("unpatched", False, False), ("patched", True, False), ]: with self.subTest(case=case): diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/serviceevents/exporter/test_otlp_attribute_vs_body_types.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/serviceevents/exporter/test_otlp_attribute_vs_body_types.py index 781d3bfdc..8b4c133b2 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/serviceevents/exporter/test_otlp_attribute_vs_body_types.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/serviceevents/exporter/test_otlp_attribute_vs_body_types.py @@ -367,13 +367,13 @@ def test_valid_attr_types_are_primitives_only(self): def test_valid_anyvalue_types_include_mapping(self): """_VALID_ANY_VALUE_TYPES includes Mapping (dict) — Body can hold dicts.""" - import typing + import collections.abc import opentelemetry.attributes as attrs valid = attrs._VALID_ANY_VALUE_TYPES - self.assertIn(typing.Mapping, valid) - self.assertIn(typing.Sequence, valid) + self.assertIn(collections.abc.Mapping, valid) + self.assertIn(collections.abc.Sequence, valid) self.assertIn(str, valid) self.assertIn(int, valid) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelementry_configurator.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelementry_configurator.py index 418cf11e7..b094bf65b 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelementry_configurator.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelementry_configurator.py @@ -129,7 +129,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - # Explicitly shut down meter provider to avoid I/O errors on Python 3.9 with gevent + # Explicitly shut down meter provider to avoid I/O errors with gevent # This ensures ConsoleMetricExporter is properly closed before Python cleanup try: meter_provider = get_meter_provider() @@ -629,7 +629,7 @@ def test_baggage_span_processor_session_id_xray_endpoint(self): processors = tracer_provider._active_span_processor._span_processors baggage_processors = [p for p in processors if p.__class__.__name__ == "BaggageSpanProcessor"] self.assertEqual(len(baggage_processors), 1) - predicate = baggage_processors[0]._baggage_key_predicate + predicate = lambda key: any(p(key) for p in baggage_processors[0]._predicates) # noqa: E731 self.assertTrue(predicate("session.id")) self.assertFalse(predicate("user.id")) @@ -647,7 +647,7 @@ def test_baggage_span_processor_custom_keys(self): processors = tracer_provider._active_span_processor._span_processors baggage_processors = [p for p in processors if p.__class__.__name__ == "BaggageSpanProcessor"] self.assertEqual(len(baggage_processors), 1) - predicate = baggage_processors[0]._baggage_key_predicate + predicate = lambda key: any(p(key) for p in baggage_processors[0]._predicates) # noqa: E731 self.assertTrue(predicate("user.id")) self.assertTrue(predicate("request.id")) self.assertTrue(predicate("session.id")) @@ -667,7 +667,7 @@ def test_baggage_span_processor_rejects_keys_without_custom_config(self): added = [c.args[0] for c in mock_tracer_provider.add_span_processor.call_args_list] baggage_processors = [p for p in added if p.__class__.__name__ == "BaggageSpanProcessor"] self.assertEqual(len(baggage_processors), 1) - predicate = baggage_processors[0]._baggage_key_predicate + predicate = lambda key: any(p(key) for p in baggage_processors[0]._predicates) # noqa: E731 self.assertFalse(predicate("any.key")) os.environ.pop("AGENT_OBSERVABILITY_ENABLED", None) @@ -684,7 +684,7 @@ def test_session_id_always_added_when_agent_observability_enabled(self): processors = tracer_provider._active_span_processor._span_processors baggage_processors = [p for p in processors if p.__class__.__name__ == "BaggageSpanProcessor"] self.assertEqual(len(baggage_processors), 1) - self.assertTrue(baggage_processors[0]._baggage_key_predicate("session.id")) + self.assertTrue(any(p("session.id") for p in baggage_processors[0]._predicates)) # With custom baggage keys, session.id should still be present alongside them os.environ["OTEL_BAGGAGE_SPAN_ATTRIBUTE_KEYS"] = "custom.key" @@ -692,7 +692,7 @@ def test_session_id_always_added_when_agent_observability_enabled(self): _customize_span_processors(tracer_provider2, Resource.get_empty(), MagicMock()) processors2 = tracer_provider2._active_span_processor._span_processors baggage_processors2 = [p for p in processors2 if p.__class__.__name__ == "BaggageSpanProcessor"] - predicate2 = baggage_processors2[0]._baggage_key_predicate + predicate2 = lambda key: any(p(key) for p in baggage_processors2[0]._predicates) # noqa: E731 self.assertTrue(predicate2("session.id")) self.assertTrue(predicate2("custom.key")) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelemetry_distro.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelemetry_distro.py index ab67f5d76..800cb81f0 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelemetry_distro.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelemetry_distro.py @@ -774,7 +774,7 @@ def test_parsing_handles_environment_markers(self): f"{self.MODULE_PATH}._get_version" ) as mock_version: mock_requires.return_value = [ - 'opentelemetry-api == 1.40.0 ; python_version >= "3.9"', + 'opentelemetry-api == 1.40.0 ; python_version >= "3.10"', "opentelemetry-sdk == 1.40.0", ] mock_version.side_effect = lambda pkg: "1.33.1" diff --git a/contract-tests/images/applications/botocore/pyproject.toml b/contract-tests/images/applications/botocore/pyproject.toml index 5c530ff96..8e5175745 100644 --- a/contract-tests/images/applications/botocore/pyproject.toml +++ b/contract-tests/images/applications/botocore/pyproject.toml @@ -3,4 +3,4 @@ name = "botocore-server" description = "Simple server that relies on botocore library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/applications/django/pyproject.toml b/contract-tests/images/applications/django/pyproject.toml index 8f7685c33..9cfbe6b2a 100644 --- a/contract-tests/images/applications/django/pyproject.toml +++ b/contract-tests/images/applications/django/pyproject.toml @@ -3,4 +3,4 @@ name = "django-server" description = "Simple server that relies on django library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/applications/mysql-connector/pyproject.toml b/contract-tests/images/applications/mysql-connector/pyproject.toml index f19ac95e8..fe67448c7 100644 --- a/contract-tests/images/applications/mysql-connector/pyproject.toml +++ b/contract-tests/images/applications/mysql-connector/pyproject.toml @@ -3,4 +3,4 @@ name = "mysql-connector-server" description = "Simple server that relies on mysql-connector library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/applications/mysqlclient/pyproject.toml b/contract-tests/images/applications/mysqlclient/pyproject.toml index b932e6c71..4c67d94f8 100644 --- a/contract-tests/images/applications/mysqlclient/pyproject.toml +++ b/contract-tests/images/applications/mysqlclient/pyproject.toml @@ -3,4 +3,4 @@ name = "mysqlclient-server" description = "Simple server that relies on mysqlclient library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/applications/mysqlclient/requirements.txt b/contract-tests/images/applications/mysqlclient/requirements.txt index 53d9a31ba..ab4e24373 100644 --- a/contract-tests/images/applications/mysqlclient/requirements.txt +++ b/contract-tests/images/applications/mysqlclient/requirements.txt @@ -1,2 +1,2 @@ typing-extensions==4.15.0 -mysqlclient==2.2.4 +mysqlclient==2.2.8 diff --git a/contract-tests/images/applications/psycopg2/pyproject.toml b/contract-tests/images/applications/psycopg2/pyproject.toml index 3aa07335a..741cc8cfc 100644 --- a/contract-tests/images/applications/psycopg2/pyproject.toml +++ b/contract-tests/images/applications/psycopg2/pyproject.toml @@ -3,4 +3,4 @@ name = "psycopg2-server" description = "Simple server that relies on psycopg2 library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/applications/pymysql/pyproject.toml b/contract-tests/images/applications/pymysql/pyproject.toml index 1ca5fcc2f..0a2b87c52 100644 --- a/contract-tests/images/applications/pymysql/pyproject.toml +++ b/contract-tests/images/applications/pymysql/pyproject.toml @@ -3,4 +3,4 @@ name = "pymysql-server" description = "Simple server that relies on pymysql library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/applications/requests/pyproject.toml b/contract-tests/images/applications/requests/pyproject.toml index 9894c46bf..461d60dd7 100644 --- a/contract-tests/images/applications/requests/pyproject.toml +++ b/contract-tests/images/applications/requests/pyproject.toml @@ -3,4 +3,4 @@ name = "requests-server" description = "Simple server that relies on requests library" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" diff --git a/contract-tests/images/mock-collector/pyproject.toml b/contract-tests/images/mock-collector/pyproject.toml index 4cfde5712..937fb0317 100644 --- a/contract-tests/images/mock-collector/pyproject.toml +++ b/contract-tests/images/mock-collector/pyproject.toml @@ -7,12 +7,12 @@ name = "mock-collector" description = "Mock Collector used by contract tests for AWS OTEL Python Instrumentation" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "grpcio ~= 1.76.0", - "opentelemetry-proto == 1.40.0", - "opentelemetry-sdk == 1.40.0", + "opentelemetry-proto == 1.42.1", + "opentelemetry-sdk == 1.42.1", "protobuf==6.33.5", "typing-extensions==4.15.0" ] diff --git a/contract-tests/images/mock-collector/requirements.txt b/contract-tests/images/mock-collector/requirements.txt index 1c7b1a640..a78fe344e 100644 --- a/contract-tests/images/mock-collector/requirements.txt +++ b/contract-tests/images/mock-collector/requirements.txt @@ -1,5 +1,5 @@ grpcio==1.76.0 -opentelemetry-proto==1.40.0 -opentelemetry-sdk==1.40.0 +opentelemetry-proto==1.42.1 +opentelemetry-sdk==1.42.1 protobuf==6.33.5 typing-extensions==4.15.0 diff --git a/contract-tests/tests/pyproject.toml b/contract-tests/tests/pyproject.toml index 6f062e306..ca8881556 100644 --- a/contract-tests/tests/pyproject.toml +++ b/contract-tests/tests/pyproject.toml @@ -7,11 +7,11 @@ name = "contract-tests" description = "Contract tests for AWS OTEL Python Instrumentation" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ - "opentelemetry-proto == 1.40.0", - "opentelemetry-sdk == 1.40.0", + "opentelemetry-proto == 1.42.1", + "opentelemetry-sdk == 1.42.1", "testcontainers==3.7.1", "grpcio==1.76.0", "docker==7.1.0", diff --git a/contract-tests/tests/test/amazon/mysqlclient/mysqlclient_test.py b/contract-tests/tests/test/amazon/mysqlclient/mysqlclient_test.py index b745c7de8..ab3193a33 100644 --- a/contract-tests/tests/test/amazon/mysqlclient/mysqlclient_test.py +++ b/contract-tests/tests/test/amazon/mysqlclient/mysqlclient_test.py @@ -1,7 +1,5 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -from typing import Dict, List - from testcontainers.mysql import MySqlContainer from typing_extensions import override @@ -11,19 +9,8 @@ DATABASE_NAME, DATABASE_PASSWORD, DATABASE_USER, - SPAN_KIND_LOCAL_ROOT, DatabaseContractTestBase, ) -from amazon.utils.application_signals_constants import ( - AWS_LOCAL_OPERATION, - AWS_LOCAL_SERVICE, - AWS_REMOTE_OPERATION, - AWS_REMOTE_RESOURCE_IDENTIFIER, - AWS_REMOTE_RESOURCE_TYPE, - AWS_REMOTE_SERVICE, - AWS_SPAN_KIND, -) -from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue class MysqlClientTest(DatabaseContractTestBase): @@ -68,35 +55,3 @@ def test_create_database_succeeds(self) -> None: def test_fault(self) -> None: self.assert_fault() - - # This adapter is not currently fully supported by OTEL - # GitHub issue: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1319 - # TODO: Once the adapter is supported, we could remove _assert_aws_attributes and - # _assert_semantic_conventions_attributes methods from this class. - @override - def _assert_aws_attributes( - self, attributes_list: List[KeyValue], expected_span_kind: str = SPAN_KIND_LOCAL_ROOT, **kwargs - ) -> None: - attributes_dict: Dict[str, AnyValue] = self._get_attributes_dict(attributes_list) - self._assert_str_attribute(attributes_dict, AWS_LOCAL_SERVICE, self.get_application_otel_service_name()) - # InternalOperation as OTEL does not instrument the basic server we are using, so the client span is a local - # root. - self._assert_str_attribute(attributes_dict, AWS_LOCAL_OPERATION, "InternalOperation") - self._assert_str_attribute(attributes_dict, AWS_REMOTE_SERVICE, self.get_remote_service()) - self._assert_str_attribute(attributes_dict, AWS_REMOTE_OPERATION, kwargs.get("sql_command")) - self.assertTrue(AWS_REMOTE_RESOURCE_TYPE not in attributes_dict) - self.assertTrue(AWS_REMOTE_RESOURCE_IDENTIFIER not in attributes_dict) - # See comment above AWS_LOCAL_OPERATION - self._assert_str_attribute(attributes_dict, AWS_SPAN_KIND, expected_span_kind) - - @override - def _assert_semantic_conventions_attributes(self, attributes_list: List[KeyValue], command: str) -> None: - attributes_dict: Dict[str, AnyValue] = self._get_attributes_dict(attributes_list) - self.assertTrue(attributes_dict.get("db.statement").string_value.startswith(command)) - self._assert_str_attribute(attributes_dict, "db.system", self.get_remote_service()) - self._assert_str_attribute(attributes_dict, "db.name", "") - self.assertTrue("net.peer.name" not in attributes_dict) - self._assert_int_attribute(attributes_dict, "net.peer.port", self.get_database_port()) - self.assertTrue("server.address" not in attributes_dict) - self.assertTrue("server.port" not in attributes_dict) - self.assertTrue("db.operation" not in attributes_dict) diff --git a/dev-requirements.txt b/dev-requirements.txt index cddbb23ce..69ed3b762 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,8 +4,7 @@ isort==5.12.0 black==24.3.0 httpretty==1.1.4 mypy==0.931 -# TODO: pin to pytest>=9 once Python 3.9 is dropped from the test matrix. -pytest>=7.1.3,<10 +pytest>=9 readme-renderer==42.0 bleach==4.1.0 # transient dependency for readme-renderer protobuf>=5.29.5 @@ -17,7 +16,7 @@ pyyaml==6.0.3 flaky==3.7.0 botocore~=1.0 # Needed so lint can resolve `import bytecode` in the DI bytecode-injection engine. It is a core -# runtime dependency (see pyproject.toml) installed on Python 3.9-3.11, but the lint env does not +# runtime dependency (see pyproject.toml) installed on Python 3.10-3.11, but the lint env does not # install the distro package itself, so it must be listed here too. bytecode>=0.13.0 flask>=2.0.0 diff --git a/lambda-layer/src/tests/requirements.txt b/lambda-layer/src/tests/requirements.txt index 08b79885c..075a8b001 100644 --- a/lambda-layer/src/tests/requirements.txt +++ b/lambda-layer/src/tests/requirements.txt @@ -1,3 +1,3 @@ # Dependencies used in tests only -opentelemetry-test-utils==0.61b0 -opentelemetry-instrumentation-aws-lambda==0.61b0 +opentelemetry-test-utils==0.63b1 +opentelemetry-instrumentation-aws-lambda==0.63b1 diff --git a/scripts/update_dependencies.py b/scripts/update_dependencies.py index 6f2d8ba9e..eecd590f9 100644 --- a/scripts/update_dependencies.py +++ b/scripts/update_dependencies.py @@ -32,7 +32,6 @@ "opentelemetry-instrumentation-aiopg", "opentelemetry-instrumentation-asgi", "opentelemetry-instrumentation-asyncpg", - "opentelemetry-instrumentation-boto", "opentelemetry-instrumentation-boto3sqs", "opentelemetry-instrumentation-botocore", "opentelemetry-instrumentation-celery", diff --git a/tox.ini b/tox.ini index d517226d9..3ceb3104e 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ skipsdist = True skip_missing_interpreters = True envlist = ; aws-opentelemetry-distro - 3.{9,10,11,12,13,14}-test-aws-opentelemetry-distro + 3.{10,11,12,13,14}-test-aws-opentelemetry-distro 3.{10,11,12,13,14}-test-aws-opentelemetry-distro-langchain-{oldest,latest} ; crewai does not support Python 3.14 yet 3.{10,11,12,13}-test-aws-opentelemetry-distro-crewai-{oldest,latest} @@ -29,8 +29,8 @@ deps = test: httpx setenv = - CORE_REPO=git+https://github.com/open-telemetry/opentelemetry-python.git@release/v1.40.x-0.61bx - CONTRIB_REPO=git+https://github.com/open-telemetry/opentelemetry-python-contrib.git@release/v1.40.x-0.61bx + CORE_REPO=git+https://github.com/open-telemetry/opentelemetry-python.git@release/v1.42.x-0.63bx + CONTRIB_REPO=git+https://github.com/open-telemetry/opentelemetry-python-contrib.git@release/v1.42.x-0.63bx COVERAGE_FILE={toxinidir}/.coverage COVERAGE_RUN=coverage run --parallel --source={envsitepackagesdir}/amazon --rcfile={toxinidir}/.coveragerc ; Enable coverage collection in subprocesses spawned during tests. @@ -42,7 +42,7 @@ changedir = commands_pre = ; Install without -e to test the actual installation - 3.{9,10,11,12,13,14}: python -m pip install -U pip setuptools wheel + 3.{10,11,12,13,14}: python -m pip install -U pip setuptools wheel ; Install common packages for all the tests. These are not needed in all the ; cases but it saves a lot of boilerplate in this file. test: pip install botocore