From 0f68b5bf9e64d73f6d6ebbad298a205940504793 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 15 Jul 2021 14:15:05 -0600 Subject: [PATCH] Remove opentelemetry-instrumentation This package will be moved to the core repo. Fixes #592 --- opentelemetry-instrumentation/MANIFEST.in | 7 - opentelemetry-instrumentation/README.rst | 112 ------------ opentelemetry-instrumentation/setup.cfg | 56 ------ opentelemetry-instrumentation/setup.py | 27 --- .../auto_instrumentation/__init__.py | 109 ------------ .../auto_instrumentation/sitecustomize.py | 135 --------------- .../instrumentation/bootstrap.py | 160 ------------------ .../instrumentation/bootstrap_gen.py | 138 --------------- .../instrumentation/configurator.py | 53 ------ .../instrumentation/dependencies.py | 64 ------- .../opentelemetry/instrumentation/distro.py | 71 -------- .../instrumentation/instrumentor.py | 132 --------------- .../instrumentation/propagators.py | 126 -------------- .../opentelemetry/instrumentation/py.typed | 0 .../opentelemetry/instrumentation/utils.py | 68 -------- .../opentelemetry/instrumentation/version.py | 15 -- .../tests/__init__.py | 0 .../tests/test_bootstrap.py | 86 ---------- .../tests/test_dependencies.py | 79 --------- .../tests/test_distro.py | 58 ------- .../tests/test_instrumentor.py | 50 ------ .../tests/test_propagators.py | 80 --------- .../tests/test_run.py | 117 ------------- .../tests/test_utils.py | 45 ----- 24 files changed, 1788 deletions(-) delete mode 100644 opentelemetry-instrumentation/MANIFEST.in delete mode 100644 opentelemetry-instrumentation/README.rst delete mode 100644 opentelemetry-instrumentation/setup.cfg delete mode 100644 opentelemetry-instrumentation/setup.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/configurator.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/propagators.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/py.typed delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py delete mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py delete mode 100644 opentelemetry-instrumentation/tests/__init__.py delete mode 100644 opentelemetry-instrumentation/tests/test_bootstrap.py delete mode 100644 opentelemetry-instrumentation/tests/test_dependencies.py delete mode 100644 opentelemetry-instrumentation/tests/test_distro.py delete mode 100644 opentelemetry-instrumentation/tests/test_instrumentor.py delete mode 100644 opentelemetry-instrumentation/tests/test_propagators.py delete mode 100644 opentelemetry-instrumentation/tests/test_run.py delete mode 100644 opentelemetry-instrumentation/tests/test_utils.py diff --git a/opentelemetry-instrumentation/MANIFEST.in b/opentelemetry-instrumentation/MANIFEST.in deleted file mode 100644 index 191b7d1959..0000000000 --- a/opentelemetry-instrumentation/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -prune tests -graft src -global-exclude *.pyc -global-exclude *.pyo -global-exclude __pycache__/* -include MANIFEST.in -include README.rst diff --git a/opentelemetry-instrumentation/README.rst b/opentelemetry-instrumentation/README.rst deleted file mode 100644 index 6f74d2232f..0000000000 --- a/opentelemetry-instrumentation/README.rst +++ /dev/null @@ -1,112 +0,0 @@ -OpenTelemetry Instrumentation -============================= - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation.svg - :target: https://pypi.org/project/opentelemetry-instrumentation/ - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation - - -This package provides a couple of commands that help automatically instruments a program: - - -opentelemetry-bootstrap ------------------------ - -:: - - opentelemetry-bootstrap --action=install|requirements - -This commands inspects the active Python site-packages and figures out which -instrumentation packages the user might want to install. By default it prints out -a list of the suggested instrumentation packages which can be added to a requirements.txt -file. It also supports installing the suggested packages when run with :code:`--action=install` -flag. - - -opentelemetry-instrument ------------------------- - -:: - - opentelemetry-instrument python program.py - -The instrument command will try to automatically detect packages used by your python program -and when possible, apply automatic tracing instrumentation on them. This means your program -will get automatic distributed tracing for free without having to make any code changes -at all. This will also configure a global tracer and tracing exporter without you having to -make any code changes. By default, the instrument command will use the OTLP exporter but -this can be overriden when needed. - -The command supports the following configuration options as CLI arguments and environment vars: - - -* ``--trace-exporter`` or ``OTEL_TRACE_EXPORTER`` - -Used to specify which trace exporter to use. Can be set to one or more of the well-known exporter -names (see below). - - - Defaults to `otlp`. - - Can be set to `none` to disable automatic tracer initialization. - -You can pass multiple values to configure multiple exporters e.g, ``zipkin,prometheus`` - -Well known trace exporter names: - - - jaeger - - opencensus - - otlp - - otlp_proto_grpc_span - - zipkin - -``otlp`` is an alias for ``otlp_proto_grpc_span``. - -* ``--id-generator`` or ``OTEL_PYTHON_ID_GENERATOR`` - -Used to specify which IDs Generator to use for the global Tracer Provider. By default, it -will use the random IDs generator. - -The code in ``program.py`` needs to use one of the packages for which there is -an OpenTelemetry integration. For a list of the available integrations please -check `here `_ - -* ``OTEL_PYTHON_DISABLED_INSTRUMENTATIONS`` - -If set by the user, opentelemetry-instrument will read this environment variable to disable specific instrumentations. -e.g OTEL_PYTHON_DISABLED_INSTRUMENTATIONS = "requests,django" - - -Examples -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -:: - - opentelemetry-instrument --trace-exporter otlp flask run --port=3000 - -The above command will pass ``--trace-exporter otlp`` to the instrument command and ``--port=3000`` to ``flask run``. - -:: - - opentelemetry-instrument --trace-exporter zipkin,otlp celery -A tasks worker --loglevel=info - -The above command will configure global trace provider, attach zipkin and otlp exporters to it and then -start celery with the rest of the arguments. - -:: - - opentelemetry-instrument --ids-generator random flask run --port=3000 - -The above command will configure the global trace provider to use the Random IDs Generator, and then -pass ``--port=3000`` to ``flask run``. - -References ----------- - -* `OpenTelemetry Project `_ diff --git a/opentelemetry-instrumentation/setup.cfg b/opentelemetry-instrumentation/setup.cfg deleted file mode 100644 index 0a62858fc7..0000000000 --- a/opentelemetry-instrumentation/setup.cfg +++ /dev/null @@ -1,56 +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. -# -[metadata] -name = opentelemetry-instrumentation -description = Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python -long_description = file: README.rst -long_description_content_type = text/x-rst -author = OpenTelemetry Authors -author_email = cncf-opentelemetry-contributors@lists.cncf.io -url = https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation -platforms = any -license = Apache-2.0 -classifiers = - Development Status :: 4 - Beta - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - -[options] -python_requires = >=3.6 -package_dir= - =src -packages=find_namespace: -zip_safe = False -include_package_data = True -install_requires = - opentelemetry-api ~= 1.3 - wrapt >= 1.0.0, < 2.0.0 - -[options.packages.find] -where = src - -[options.entry_points] -console_scripts = - opentelemetry-instrument = opentelemetry.instrumentation.auto_instrumentation:run - opentelemetry-bootstrap = opentelemetry.instrumentation.bootstrap:run - -[options.extras_require] -test = diff --git a/opentelemetry-instrumentation/setup.py b/opentelemetry-instrumentation/setup.py deleted file mode 100644 index fb3c8ff9f1..0000000000 --- a/opentelemetry-instrumentation/setup.py +++ /dev/null @@ -1,27 +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 os - -import setuptools - -BASE_DIR = os.path.dirname(__file__) -VERSION_FILENAME = os.path.join( - BASE_DIR, "src", "opentelemetry", "instrumentation", "version.py" -) -PACKAGE_INFO = {} -with open(VERSION_FILENAME) as f: - exec(f.read(), PACKAGE_INFO) - -setuptools.setup(version=PACKAGE_INFO["__version__"],) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py deleted file mode 100644 index 45a1f2a221..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python3 - -# 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 argparse -from logging import getLogger -from os import environ, execl, getcwd -from os.path import abspath, dirname, pathsep -from shutil import which - -from opentelemetry.environment_variables import ( - OTEL_PYTHON_ID_GENERATOR, - OTEL_TRACES_EXPORTER, -) - -logger = getLogger(__file__) - - -def parse_args(): - parser = argparse.ArgumentParser( - description=""" - opentelemetry-instrument automatically instruments a Python - program and it's dependencies and then runs the program. - """ - ) - - parser.add_argument( - "--trace-exporter", - required=False, - help=""" - Uses the specified exporter to export spans. - Accepts multiple exporters as comma separated values. - - Examples: - - --trace-exporter=jaeger - """, - ) - - parser.add_argument( - "--id-generator", - required=False, - help=""" - The IDs Generator to be used with the Tracer Provider. - - Examples: - - --id-generator=random - """, - ) - - parser.add_argument("command", help="Your Python application.") - parser.add_argument( - "command_args", - help="Arguments for your application.", - nargs=argparse.REMAINDER, - ) - return parser.parse_args() - - -def load_config_from_cli_args(args): - if args.trace_exporter: - environ[OTEL_TRACES_EXPORTER] = args.trace_exporter - if args.id_generator: - environ[OTEL_PYTHON_ID_GENERATOR] = args.id_generator - - -def run() -> None: - args = parse_args() - load_config_from_cli_args(args) - - python_path = environ.get("PYTHONPATH") - - if not python_path: - python_path = [] - - else: - python_path = python_path.split(pathsep) - - cwd_path = getcwd() - - # This is being added to support applications that are being run from their - # own executable, like Django. - # FIXME investigate if there is another way to achieve this - if cwd_path not in python_path: - python_path.insert(0, cwd_path) - - filedir_path = dirname(abspath(__file__)) - - python_path = [path for path in python_path if path != filedir_path] - - python_path.insert(0, filedir_path) - - environ["PYTHONPATH"] = pathsep.join(python_path) - - executable = which(args.command) - execl(executable, executable, *args.command_args) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py deleted file mode 100644 index d89b60ec56..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py +++ /dev/null @@ -1,135 +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 sys -from logging import getLogger -from os import environ, path -from os.path import abspath, dirname, pathsep -from re import sub - -from pkg_resources import iter_entry_points - -from opentelemetry.environment_variables import ( - OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, -) -from opentelemetry.instrumentation.dependencies import ( - get_dist_dependency_conflicts, -) -from opentelemetry.instrumentation.distro import BaseDistro, DefaultDistro - -logger = getLogger(__file__) - - -def _load_distros() -> BaseDistro: - for entry_point in iter_entry_points("opentelemetry_distro"): - try: - distro = entry_point.load()() - if not isinstance(distro, BaseDistro): - logger.debug( - "%s is not an OpenTelemetry Distro. Skipping", - entry_point.name, - ) - continue - logger.debug( - "Distribution %s will be configured", entry_point.name - ) - return distro - except Exception as exc: # pylint: disable=broad-except - logger.exception( - "Distribution %s configuration failed", entry_point.name - ) - raise exc - return DefaultDistro() - - -def _load_instrumentors(distro): - package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, []) - 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_instrumentor"): - if entry_point.name in package_to_exclude: - logger.debug( - "Instrumentation skipped for library %s", entry_point.name - ) - continue - - try: - conflict = get_dist_dependency_conflicts(entry_point.dist) - if conflict: - logger.debug( - "Skipping instrumentation %s: %s", - entry_point.name, - conflict, - ) - continue - - # 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 Exception as exc: # pylint: disable=broad-except - logger.exception("Instrumenting of %s failed", entry_point.name) - raise exc - - -def _load_configurators(): - configured = None - for entry_point in iter_entry_points("opentelemetry_configurator"): - if configured is not None: - logger.warning( - "Configuration of %s not loaded, %s already loaded", - entry_point.name, - configured, - ) - continue - try: - entry_point.load()().configure() # type: ignore - configured = entry_point.name - except Exception as exc: # pylint: disable=broad-except - logger.exception("Configuration of %s failed", entry_point.name) - raise exc - - -def initialize(): - try: - distro = _load_distros() - distro.configure() - _load_configurators() - _load_instrumentors(distro) - except Exception: # pylint: disable=broad-except - logger.exception("Failed to auto initialize opentelemetry") - finally: - environ["PYTHONPATH"] = sub( - r"{}{}?".format(dirname(abspath(__file__)), pathsep), - "", - environ["PYTHONPATH"], - ) - - -if ( - hasattr(sys, "argv") - and sys.argv[0].split(path.sep)[-1] == "celery" - and "worker" in sys.argv[1:] -): - from celery.signals import worker_process_init # pylint:disable=E0401 - - @worker_process_init.connect(weak=False) - def init_celery(*args, **kwargs): - initialize() - - -else: - initialize() diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py deleted file mode 100644 index e691f0c360..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 - -# 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 argparse -import logging -import subprocess -import sys - -import pkg_resources - -from opentelemetry.instrumentation.bootstrap_gen import ( - default_instrumentations, - libraries, -) -from opentelemetry.instrumentation.version import __version__ as version - -logger = logging.getLogger(__file__) - - -def _syscall(func): - def wrapper(package=None): - try: - if package: - return func(package) - return func() - except subprocess.SubprocessError as exp: - cmd = getattr(exp, "cmd", None) - if cmd: - msg = 'Error calling system command "{0}"'.format( - " ".join(cmd) - ) - if package: - msg = '{0} for package "{1}"'.format(msg, package) - raise RuntimeError(msg) - - return wrapper - - -@_syscall -def _sys_pip_install(package): - # explicit upgrade strategy to override potential pip config - subprocess.check_call( - [ - sys.executable, - "-m", - "pip", - "install", - "-U", - "--upgrade-strategy", - "only-if-needed", - package, - ] - ) - - -def _pip_check(): - """Ensures none of the instrumentations have dependency conflicts. - Clean check reported as: - 'No broken requirements found.' - Dependency conflicts are reported as: - 'opentelemetry-instrumentation-flask 1.0.1 has requirement opentelemetry-sdk<2.0,>=1.0, but you have opentelemetry-sdk 0.5.' - To not be too restrictive, we'll only check for relevant packages. - """ - # pylint: disable=consider-using-with - check_pipe = subprocess.Popen( - [sys.executable, "-m", "pip", "check"], stdout=subprocess.PIPE - ) - pip_check = check_pipe.communicate()[0].decode() - pip_check_lower = pip_check.lower() - for package_tup in libraries.values(): - for package in package_tup: - if package.lower() in pip_check_lower: - raise RuntimeError( - "Dependency conflict found: {}".format(pip_check) - ) - - -def _is_installed(req): - if req in sys.modules: - return True - - try: - pkg_resources.get_distribution(req) - except pkg_resources.DistributionNotFound: - return False - except pkg_resources.VersionConflict as exc: - logger.warning( - "instrumentation for package %s is available but version %s is installed. Skipping.", - exc.req, - exc.dist.as_requirement(), # pylint: disable=no-member - ) - return False - return True - - -def _find_installed_libraries(): - libs = default_instrumentations[:] - libs.extend( - [ - v["instrumentation"] - for _, v in libraries.items() - if _is_installed(v["library"]) - ] - ) - return libs - - -def _run_requirements(): - logger.setLevel(logging.ERROR) - print("\n".join(_find_installed_libraries()), end="") - - -def _run_install(): - for lib in _find_installed_libraries(): - _sys_pip_install(lib) - _pip_check() - - -def run() -> None: - action_install = "install" - action_requirements = "requirements" - - parser = argparse.ArgumentParser( - description=""" - opentelemetry-bootstrap detects installed libraries and automatically - installs the relevant instrumentation packages for them. - """ - ) - parser.add_argument( - "-a", - "--action", - choices=[action_install, action_requirements], - default=action_requirements, - help=""" - install - uses pip to install the new requirements using to the - currently active site-package. - requirements - prints out the new requirements to stdout. Action can - be piped and appended to a requirements.txt file. - """, - ) - args = parser.parse_args() - - cmd = { - action_install: _run_install, - action_requirements: _run_requirements, - }[args.action] - cmd() diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py deleted file mode 100644 index b49f40905f..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ /dev/null @@ -1,138 +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. - -# DO NOT EDIT. THIS FILE WAS AUTOGENERATED FROM INSTRUMENTATION PACKAGES. -# RUN `python scripts/generate_instrumentation_bootstrap.py` TO REGENERATE. - -libraries = { - "aiohttp": { - "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.23.dev0", - }, - "aiopg": { - "library": "aiopg >= 0.13.0, < 1.3.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.23.dev0", - }, - "asgiref": { - "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.23.dev0", - }, - "asyncpg": { - "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.23.dev0", - }, - "boto": { - "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.23.dev0", - }, - "botocore": { - "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.23.dev0", - }, - "celery": { - "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.23.dev0", - }, - "django": { - "library": "django >= 1.10", - "instrumentation": "opentelemetry-instrumentation-django==0.23.dev0", - }, - "elasticsearch": { - "library": "elasticsearch >= 2.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.23.dev0", - }, - "falcon": { - "library": "falcon ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-falcon==0.23.dev0", - }, - "fastapi": { - "library": "fastapi ~= 0.58.1", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.23.dev0", - }, - "flask": { - "library": "flask >= 1.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.23.dev0", - }, - "grpcio": { - "library": "grpcio ~= 1.27", - "instrumentation": "opentelemetry-instrumentation-grpc==0.23.dev0", - }, - "httpx": { - "library": "httpx >= 0.18.0, < 0.19.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.23.dev0", - }, - "jinja2": { - "library": "jinja2~=2.7", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.23.dev0", - }, - "mysql-connector-python": { - "library": "mysql-connector-python ~= 8.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.23.dev0", - }, - "psycopg2": { - "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.23.dev0", - }, - "pymemcache": { - "library": "pymemcache ~= 1.3", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.23.dev0", - }, - "pymongo": { - "library": "pymongo ~= 3.1", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.23.dev0", - }, - "PyMySQL": { - "library": "PyMySQL ~= 0.10.1", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.23.dev0", - }, - "pyramid": { - "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.23.dev0", - }, - "redis": { - "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.23.dev0", - }, - "requests": { - "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.23.dev0", - }, - "scikit-learn": { - "library": "scikit-learn ~= 0.24.0", - "instrumentation": "opentelemetry-instrumentation-sklearn==0.23.dev0", - }, - "sqlalchemy": { - "library": "sqlalchemy", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.23.dev0", - }, - "starlette": { - "library": "starlette ~= 0.13.0", - "instrumentation": "opentelemetry-instrumentation-starlette==0.23.dev0", - }, - "tornado": { - "library": "tornado >= 6.0", - "instrumentation": "opentelemetry-instrumentation-tornado==0.23.dev0", - }, - "urllib3": { - "library": "urllib3 >= 1.0.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.23.dev0", - }, -} -default_instrumentations = [ - "opentelemetry-instrumentation-dbapi==0.23.dev0", - "opentelemetry-instrumentation-logging==0.23.dev0", - "opentelemetry-instrumentation-sqlite3==0.23.dev0", - "opentelemetry-instrumentation-urllib==0.23.dev0", - "opentelemetry-instrumentation-wsgi==0.23.dev0", -] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/configurator.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/configurator.py deleted file mode 100644 index 3efa71e89e..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/configurator.py +++ /dev/null @@ -1,53 +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. -# type: ignore - -""" -OpenTelemetry Base Configurator -""" - -from abc import ABC, abstractmethod -from logging import getLogger - -_LOG = getLogger(__name__) - - -class BaseConfigurator(ABC): - """An ABC for configurators - - Configurators are used to configure - SDKs (i.e. TracerProvider, MeterProvider, Processors...) - to reduce the amount of manual configuration required. - """ - - _instance = None - _is_instrumented = False - - def __new__(cls, *args, **kwargs): - - if cls._instance is None: - cls._instance = object.__new__(cls, *args, **kwargs) - - return cls._instance - - @abstractmethod - def _configure(self, **kwargs): - """Configure the SDK""" - - def configure(self, **kwargs): - """Configure the SDK""" - self._configure(**kwargs) - - -__all__ = ["BaseConfigurator"] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py deleted file mode 100644 index 0cec55769c..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py +++ /dev/null @@ -1,64 +0,0 @@ -from logging import getLogger -from typing import Collection, Optional - -from pkg_resources import ( - Distribution, - DistributionNotFound, - RequirementParseError, - VersionConflict, - get_distribution, -) - -logger = getLogger(__file__) - - -class DependencyConflict: - required: str = None - found: Optional[str] = None - - def __init__(self, required, found=None): - self.required = required - self.found = found - - def __str__(self): - return 'DependencyConflict: requested: "{0}" but found: "{1}"'.format( - self.required, self.found - ) - - -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)) - - return get_dependency_conflicts(instrumentation_deps) - - -def get_dependency_conflicts( - deps: Collection[str], -) -> Optional[DependencyConflict]: - for dep in deps: - 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, - ) - return DependencyConflict(dep) - return None diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py deleted file mode 100644 index cc1c99c1e0..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py +++ /dev/null @@ -1,71 +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. -# type: ignore - -""" -OpenTelemetry Base Distribution (Distro) -""" - -from abc import ABC, abstractmethod -from logging import getLogger - -from pkg_resources import EntryPoint - -from opentelemetry.instrumentation.instrumentor import BaseInstrumentor - -_LOG = getLogger(__name__) - - -class BaseDistro(ABC): - """An ABC for distro""" - - _instance = None - - def __new__(cls, *args, **kwargs): - - if cls._instance is None: - cls._instance = object.__new__(cls, *args, **kwargs) - - return cls._instance - - @abstractmethod - def _configure(self, **kwargs): - """Configure the distribution""" - - def configure(self, **kwargs): - """Configure the distribution""" - self._configure(**kwargs) - - def load_instrumentor( # pylint: disable=no-self-use - self, entry_point: EntryPoint, **kwargs - ): - """Takes a collection of instrumentation entry points - and activates them by instantiating and calling instrument() - on each one. - - Distros can override this method to customize the behavior by - inspecting each entry point and configuring them in special ways, - passing additional arguments, load a replacement/fork instead, - skip loading entirely, etc. - """ - instrumentor: BaseInstrumentor = entry_point.load() - instrumentor().instrument(**kwargs) - - -class DefaultDistro(BaseDistro): - def _configure(self, **kwargs): - pass - - -__all__ = ["BaseDistro", "DefaultDistro"] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py deleted file mode 100644 index 74ebe86746..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py +++ /dev/null @@ -1,132 +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. -# type: ignore - -""" -OpenTelemetry Base Instrumentor -""" - -from abc import ABC, abstractmethod -from logging import getLogger -from typing import Collection, Optional - -from opentelemetry.instrumentation.dependencies import ( - DependencyConflict, - get_dependency_conflicts, -) - -_LOG = getLogger(__name__) - - -class BaseInstrumentor(ABC): - """An ABC for instrumentors - - Child classes of this ABC should instrument specific third - party libraries or frameworks either by using the - ``opentelemetry-instrument`` command or by calling their methods - directly. - - Since every third party library or framework is different and has different - instrumentation needs, more methods can be added to the child classes as - needed to provide practical instrumentation to the end user. - """ - - _instance = None - _is_instrumented_by_opentelemetry = False - - def __new__(cls, *args, **kwargs): - - if cls._instance is None: - cls._instance = object.__new__(cls, *args, **kwargs) - - return cls._instance - - @property - def is_instrumented_by_opentelemetry(self): - return self._is_instrumented_by_opentelemetry - - @abstractmethod - def instrumentation_dependencies(self) -> Collection[str]: - """Return a list of python packages with versions that the will be instrumented. - - The format should be the same as used in requirements.txt or setup.py. - - For example, if an instrumentation instruments requests 1.x, this method should look - like: - - def instrumentation_dependencies(self) -> Collection[str]: - return ['requests ~= 1.0'] - - This will ensure that the instrumentation will only be used when the specified library - is present in the environment. - """ - - def _instrument(self, **kwargs): - """Instrument the library""" - - @abstractmethod - def _uninstrument(self, **kwargs): - """Uninstrument the library""" - - def _check_dependency_conflicts(self) -> Optional[DependencyConflict]: - dependencies = self.instrumentation_dependencies() - return get_dependency_conflicts(dependencies) - - def instrument(self, **kwargs): - """Instrument the library - - This method will be called without any optional arguments by the - ``opentelemetry-instrument`` command. - - This means that calling this method directly without passing any - optional values should do the very same thing that the - ``opentelemetry-instrument`` command does. - """ - - if self._is_instrumented_by_opentelemetry: - _LOG.warning("Attempting to instrument while already instrumented") - return None - - # check if instrumentor has any missing or conflicting dependencies - skip_dep_check = kwargs.pop("skip_dep_check", False) - if not skip_dep_check: - conflict = self._check_dependency_conflicts() - if conflict: - _LOG.error(conflict) - return None - - result = self._instrument( # pylint: disable=assignment-from-no-return - **kwargs - ) - self._is_instrumented_by_opentelemetry = True - return result - - def uninstrument(self, **kwargs): - """Uninstrument the library - - See ``BaseInstrumentor.instrument`` for more information regarding the - usage of ``kwargs``. - """ - - if self._is_instrumented_by_opentelemetry: - result = self._uninstrument(**kwargs) - self._is_instrumented_by_opentelemetry = False - return result - - _LOG.warning("Attempting to uninstrument while already uninstrumented") - - return None - - -__all__ = ["BaseInstrumentor"] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/propagators.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/propagators.py deleted file mode 100644 index 3243e1a886..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/propagators.py +++ /dev/null @@ -1,126 +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 module implements experimental propagators to inject trace context -into response carriers. This is useful for server side frameworks that start traces -when server requests and want to share the trace context with the client so the -client can add it's spans to the same trace. - -This is part of an upcoming W3C spec and will eventually make it to the Otel spec. - -https://w3c.github.io/trace-context/#trace-context-http-response-headers-format -""" - -import typing -from abc import ABC, abstractmethod - -from opentelemetry import trace -from opentelemetry.context.context import Context -from opentelemetry.propagators import textmap -from opentelemetry.trace import format_span_id, format_trace_id - -_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers" -_RESPONSE_PROPAGATOR = None - - -def get_global_response_propagator(): - return _RESPONSE_PROPAGATOR - - -def set_global_response_propagator(propagator): - global _RESPONSE_PROPAGATOR # pylint:disable=global-statement - _RESPONSE_PROPAGATOR = propagator - - -class Setter(ABC): - @abstractmethod - def set(self, carrier, key, value): - """Inject the provided key value pair in carrier.""" - - -class DictHeaderSetter(Setter): - def set(self, carrier, key, value): # pylint: disable=no-self-use - old_value = carrier.get(key, "") - if old_value: - value = "{0}, {1}".format(old_value, value) - carrier[key] = value - - -class FuncSetter(Setter): - """FuncSetter coverts a function into a valid Setter. Any function that can - set values in a carrier can be converted into a Setter by using FuncSetter. - This is useful when injecting trace context into non-dict objects such - HTTP Response objects for different framework. - - For example, it can be used to create a setter for Falcon response object as: - - setter = FuncSetter(falcon.api.Response.append_header) - - and then used with the propagator as: - - propagator.inject(falcon_response, setter=setter) - - This would essentially make the propagator call `falcon_response.append_header(key, value)` - """ - - def __init__(self, func): - self._func = func - - def set(self, carrier, key, value): - self._func(carrier, key, value) - - -default_setter = DictHeaderSetter() - - -class ResponsePropagator(ABC): - @abstractmethod - def inject( - self, - carrier: textmap.CarrierT, - context: typing.Optional[Context] = None, - setter: textmap.Setter = default_setter, - ) -> None: - """Injects SpanContext into the HTTP response carrier.""" - - -class TraceResponsePropagator(ResponsePropagator): - """Experimental propagator that injects tracecontext into HTTP responses.""" - - def inject( - self, - carrier: textmap.CarrierT, - context: typing.Optional[Context] = None, - setter: textmap.Setter = default_setter, - ) -> None: - """Injects SpanContext into the HTTP response carrier.""" - span = trace.get_current_span(context) - span_context = span.get_span_context() - if span_context == trace.INVALID_SPAN_CONTEXT: - return - - header_name = "traceresponse" - setter.set( - carrier, - header_name, - "00-{trace_id}-{span_id}-{:02x}".format( - span_context.trace_flags, - trace_id=format_trace_id(span_context.trace_id), - span_id=format_span_id(span_context.span_id), - ), - ) - setter.set( - carrier, _HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, header_name, - ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/py.typed b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/py.typed deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py deleted file mode 100644 index 16f75aae6c..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ /dev/null @@ -1,68 +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. - -from typing import Dict, Sequence - -from wrapt import ObjectProxy - -from opentelemetry.context import create_key -from opentelemetry.trace import StatusCode - -# FIXME This is a temporary location for the suppress instrumentation key. -# Once the decision around how to suppress instrumentation is made in the -# spec, this key should be moved accordingly. -_SUPPRESS_INSTRUMENTATION_KEY = create_key("suppress_instrumentation") - - -def extract_attributes_from_object( - obj: any, attributes: Sequence[str], existing: Dict[str, str] = None -) -> Dict[str, str]: - extracted = {} - if existing: - extracted.update(existing) - for attr in attributes: - value = getattr(obj, attr, None) - if value is not None: - extracted[attr] = str(value) - return extracted - - -def http_status_to_status_code( - status: int, allow_redirect: bool = True -) -> StatusCode: - """Converts an HTTP status code to an OpenTelemetry canonical status code - - Args: - status (int): HTTP status code - """ - # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status - if status < 100: - return StatusCode.ERROR - if status <= 299: - return StatusCode.UNSET - if status <= 399 and allow_redirect: - return StatusCode.UNSET - return StatusCode.ERROR - - -def unwrap(obj, attr: str): - """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it - - Args: - obj: Object that holds a reference to the wrapped function - attr (str): Name of the wrapped function - """ - 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 deleted file mode 100644 index c829b95757..0000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__version__ = "0.23.dev0" diff --git a/opentelemetry-instrumentation/tests/__init__.py b/opentelemetry-instrumentation/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/opentelemetry-instrumentation/tests/test_bootstrap.py b/opentelemetry-instrumentation/tests/test_bootstrap.py deleted file mode 100644 index d1052de289..0000000000 --- a/opentelemetry-instrumentation/tests/test_bootstrap.py +++ /dev/null @@ -1,86 +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. -# type: ignore - -from io import StringIO -from random import sample -from unittest import TestCase -from unittest.mock import call, patch - -from opentelemetry.instrumentation import bootstrap -from opentelemetry.instrumentation.bootstrap_gen import libraries - - -def sample_packages(packages, rate): - return sample(list(packages), int(len(packages) * rate),) - - -class TestBootstrap(TestCase): - - installed_libraries = {} - installed_instrumentations = {} - - @classmethod - def setUpClass(cls): - cls.installed_libraries = sample_packages( - [lib["instrumentation"] for lib in libraries.values()], 0.6 - ) - - # treat 50% of sampled packages as pre-installed - cls.installed_instrumentations = sample_packages( - cls.installed_libraries, 0.5 - ) - - cls.pkg_patcher = patch( - "opentelemetry.instrumentation.bootstrap._find_installed_libraries", - return_value=cls.installed_libraries, - ) - - cls.pip_install_patcher = patch( - "opentelemetry.instrumentation.bootstrap._sys_pip_install", - ) - cls.pip_check_patcher = patch( - "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() - - @classmethod - def tearDownClass(cls): - cls.pip_check_patcher.start() - cls.pip_install_patcher.start() - cls.pkg_patcher.stop() - - @patch("sys.argv", ["bootstrap", "-a", "pipenv"]) - def test_run_unknown_cmd(self): - with self.assertRaises(SystemExit): - bootstrap.run() - - @patch("sys.argv", ["bootstrap", "-a", "requirements"]) - def test_run_cmd_print(self): - with patch("sys.stdout", new=StringIO()) as fake_out: - bootstrap.run() - self.assertEqual( - fake_out.getvalue(), "\n".join(self.installed_libraries), - ) - - @patch("sys.argv", ["bootstrap", "-a", "install"]) - def test_run_cmd_install(self): - 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) diff --git a/opentelemetry-instrumentation/tests/test_dependencies.py b/opentelemetry-instrumentation/tests/test_dependencies.py deleted file mode 100644 index 8b2f2e9b39..0000000000 --- a/opentelemetry-instrumentation/tests/test_dependencies.py +++ /dev/null @@ -1,79 +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. - -# pylint: disable=protected-access - -import pkg_resources -import pytest - -from opentelemetry.instrumentation.dependencies import ( - DependencyConflict, - get_dependency_conflicts, - get_dist_dependency_conflicts, -) -from opentelemetry.test.test_base import TestBase - - -class TestDependencyConflicts(TestBase): - def setUp(self): - pass - - def test_get_dependency_conflicts_empty(self): - self.assertIsNone(get_dependency_conflicts([])) - - def test_get_dependency_conflicts_no_conflict(self): - self.assertIsNone(get_dependency_conflicts(["pytest"])) - - def test_get_dependency_conflicts_not_installed(self): - conflict = get_dependency_conflicts(["this-package-does-not-exist"]) - 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_mismatched_version(self): - conflict = get_dependency_conflicts(["pytest == 5000"]) - self.assertTrue(conflict is not None) - self.assertTrue(isinstance(conflict, DependencyConflict)) - self.assertEqual( - str(conflict), - 'DependencyConflict: requested: "pytest == 5000" but found: "pytest {0}"'.format( - pytest.__version__ - ), - ) - - 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 [] - - dist = pkg_resources.Distribution( - project_name="test-instrumentation", version="1.0" - ) - dist.requires = mock_requires - - 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"', - ) diff --git a/opentelemetry-instrumentation/tests/test_distro.py b/opentelemetry-instrumentation/tests/test_distro.py deleted file mode 100644 index 399b3f8a65..0000000000 --- a/opentelemetry-instrumentation/tests/test_distro.py +++ /dev/null @@ -1,58 +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. -# type: ignore - -from unittest import TestCase - -from pkg_resources import EntryPoint - -from opentelemetry.instrumentation.distro import BaseDistro -from opentelemetry.instrumentation.instrumentor import BaseInstrumentor - - -class MockInstrumetor(BaseInstrumentor): - def instrumentation_dependencies(self): - return [] - - def _instrument(self, **kwargs): - pass - - def _uninstrument(self, **kwargs): - pass - - -class MockEntryPoint(EntryPoint): - def __init__(self, obj): # pylint: disable=super-init-not-called - self._obj = obj - - def load(self, *args, **kwargs): # pylint: disable=signature-differs - return self._obj - - -class MockDistro(BaseDistro): - def _configure(self, **kwargs): - pass - - -class TestDistro(TestCase): - def test_load_instrumentor(self): - # pylint: disable=protected-access - distro = MockDistro() - - instrumentor = MockInstrumetor() - entry_point = MockEntryPoint(MockInstrumetor) - - self.assertFalse(instrumentor._is_instrumented_by_opentelemetry) - distro.load_instrumentor(entry_point) - self.assertTrue(instrumentor._is_instrumented_by_opentelemetry) diff --git a/opentelemetry-instrumentation/tests/test_instrumentor.py b/opentelemetry-instrumentation/tests/test_instrumentor.py deleted file mode 100644 index dee32c34e4..0000000000 --- a/opentelemetry-instrumentation/tests/test_instrumentor.py +++ /dev/null @@ -1,50 +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. -# type: ignore - -from logging import WARNING -from unittest import TestCase - -from opentelemetry.instrumentation.instrumentor import BaseInstrumentor - - -class TestInstrumentor(TestCase): - class Instrumentor(BaseInstrumentor): - def _instrument(self, **kwargs): - return "instrumented" - - def _uninstrument(self, **kwargs): - return "uninstrumented" - - def instrumentation_dependencies(self): - return [] - - def test_protect(self): - instrumentor = self.Instrumentor() - - with self.assertLogs(level=WARNING): - self.assertIs(instrumentor.uninstrument(), None) - - self.assertEqual(instrumentor.instrument(), "instrumented") - - with self.assertLogs(level=WARNING): - self.assertIs(instrumentor.instrument(), None) - - self.assertEqual(instrumentor.uninstrument(), "uninstrumented") - - with self.assertLogs(level=WARNING): - self.assertIs(instrumentor.uninstrument(), None) - - def test_singleton(self): - self.assertIs(self.Instrumentor(), self.Instrumentor()) diff --git a/opentelemetry-instrumentation/tests/test_propagators.py b/opentelemetry-instrumentation/tests/test_propagators.py deleted file mode 100644 index 62461aafa9..0000000000 --- a/opentelemetry-instrumentation/tests/test_propagators.py +++ /dev/null @@ -1,80 +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. - -# pylint: disable=protected-access - -from opentelemetry import trace -from opentelemetry.instrumentation import propagators -from opentelemetry.instrumentation.propagators import ( - DictHeaderSetter, - TraceResponsePropagator, - get_global_response_propagator, - set_global_response_propagator, -) -from opentelemetry.test.test_base import TestBase - - -class TestGlobals(TestBase): - def test_get_set(self): - original = propagators._RESPONSE_PROPAGATOR - - propagators._RESPONSE_PROPAGATOR = None - self.assertIsNone(get_global_response_propagator()) - - prop = TraceResponsePropagator() - set_global_response_propagator(prop) - self.assertIs(prop, get_global_response_propagator()) - - propagators._RESPONSE_PROPAGATOR = original - - -class TestDictHeaderSetter(TestBase): - def test_simple(self): - setter = DictHeaderSetter() - carrier = {} - setter.set(carrier, "kk", "vv") - self.assertIn("kk", carrier) - self.assertEqual(carrier["kk"], "vv") - - def test_append(self): - setter = DictHeaderSetter() - carrier = {"kk": "old"} - setter.set(carrier, "kk", "vv") - self.assertIn("kk", carrier) - self.assertEqual(carrier["kk"], "old, vv") - - -class TestTraceResponsePropagator(TestBase): - def test_inject(self): - span = trace.NonRecordingSpan( - trace.SpanContext( - trace_id=1, - span_id=2, - is_remote=False, - trace_flags=trace.DEFAULT_TRACE_OPTIONS, - trace_state=trace.DEFAULT_TRACE_STATE, - ), - ) - - ctx = trace.set_span_in_context(span) - prop = TraceResponsePropagator() - carrier = {} - prop.inject(carrier, ctx) - self.assertEqual( - carrier["Access-Control-Expose-Headers"], "traceresponse" - ) - self.assertEqual( - carrier["traceresponse"], - "00-00000000000000000000000000000001-0000000000000002-00", - ) diff --git a/opentelemetry-instrumentation/tests/test_run.py b/opentelemetry-instrumentation/tests/test_run.py deleted file mode 100644 index 01bd86ed32..0000000000 --- a/opentelemetry-instrumentation/tests/test_run.py +++ /dev/null @@ -1,117 +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. -# type: ignore - -from os import environ, getcwd -from os.path import abspath, dirname, pathsep -from unittest import TestCase -from unittest.mock import patch - -from opentelemetry.environment_variables import OTEL_TRACES_EXPORTER -from opentelemetry.instrumentation import auto_instrumentation - - -class TestRun(TestCase): - auto_instrumentation_path = dirname(abspath(auto_instrumentation.__file__)) - - @classmethod - def setUpClass(cls): - cls.execl_patcher = patch( - "opentelemetry.instrumentation.auto_instrumentation.execl" - ) - cls.which_patcher = patch( - "opentelemetry.instrumentation.auto_instrumentation.which" - ) - - cls.execl_patcher.start() - cls.which_patcher.start() - - @classmethod - def tearDownClass(cls): - cls.execl_patcher.stop() - cls.which_patcher.stop() - - @patch("sys.argv", ["instrument", ""]) - @patch.dict("os.environ", {"PYTHONPATH": ""}) - def test_empty(self): - auto_instrumentation.run() - self.assertEqual( - environ["PYTHONPATH"], - pathsep.join([self.auto_instrumentation_path, getcwd()]), - ) - - @patch("sys.argv", ["instrument", ""]) - @patch.dict("os.environ", {"PYTHONPATH": "abc"}) - def test_non_empty(self): - auto_instrumentation.run() - self.assertEqual( - environ["PYTHONPATH"], - pathsep.join([self.auto_instrumentation_path, getcwd(), "abc"]), - ) - - @patch("sys.argv", ["instrument", ""]) - @patch.dict( - "os.environ", - {"PYTHONPATH": pathsep.join(["abc", auto_instrumentation_path])}, - ) - def test_after_path(self): - auto_instrumentation.run() - self.assertEqual( - environ["PYTHONPATH"], - pathsep.join([self.auto_instrumentation_path, getcwd(), "abc"]), - ) - - @patch("sys.argv", ["instrument", ""]) - @patch.dict( - "os.environ", - { - "PYTHONPATH": pathsep.join( - [auto_instrumentation_path, "abc", auto_instrumentation_path] - ) - }, - ) - def test_single_path(self): - auto_instrumentation.run() - self.assertEqual( - environ["PYTHONPATH"], - pathsep.join([self.auto_instrumentation_path, getcwd(), "abc"]), - ) - - -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 - mock_which.configure_mock(**{"return_value": "python"}) - - auto_instrumentation.run() - - mock_execl.assert_called_with("python", "python", "3") - - -class TestArgs(TestCase): - @patch("opentelemetry.instrumentation.auto_instrumentation.execl") - def test_exporter(self, _): # pylint: disable=no-self-use - with patch("sys.argv", ["instrument", "2"]): - auto_instrumentation.run() - self.assertIsNone(environ.get(OTEL_TRACES_EXPORTER)) - - with patch( - "sys.argv", ["instrument", "--trace-exporter", "jaeger", "1", "2"] - ): - auto_instrumentation.run() - self.assertEqual(environ.get(OTEL_TRACES_EXPORTER), "jaeger") diff --git a/opentelemetry-instrumentation/tests/test_utils.py b/opentelemetry-instrumentation/tests/test_utils.py deleted file mode 100644 index 273c6f085c..0000000000 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ /dev/null @@ -1,45 +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. - -from http import HTTPStatus - -from opentelemetry.instrumentation.utils import http_status_to_status_code -from opentelemetry.test.test_base import TestBase -from opentelemetry.trace import StatusCode - - -class TestUtils(TestBase): - # 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): - for status_code, expected in ( - (HTTPStatus.OK, StatusCode.UNSET), - (HTTPStatus.ACCEPTED, StatusCode.UNSET), - (HTTPStatus.IM_USED, StatusCode.UNSET), - (HTTPStatus.MULTIPLE_CHOICES, StatusCode.UNSET), - (HTTPStatus.BAD_REQUEST, StatusCode.ERROR), - (HTTPStatus.UNAUTHORIZED, StatusCode.ERROR), - (HTTPStatus.FORBIDDEN, StatusCode.ERROR), - (HTTPStatus.NOT_FOUND, StatusCode.ERROR), - (HTTPStatus.UNPROCESSABLE_ENTITY, StatusCode.ERROR,), - (HTTPStatus.TOO_MANY_REQUESTS, StatusCode.ERROR,), - (HTTPStatus.NOT_IMPLEMENTED, StatusCode.ERROR), - (HTTPStatus.SERVICE_UNAVAILABLE, StatusCode.ERROR), - (HTTPStatus.GATEWAY_TIMEOUT, StatusCode.ERROR,), - (HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, StatusCode.ERROR,), - (600, StatusCode.ERROR), - (99, StatusCode.ERROR), - ): - with self.subTest(status_code=status_code): - actual = http_status_to_status_code(int(status_code)) - self.assertEqual(actual, expected, status_code)