diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 48d109f5ef6..d564f69c672 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -23,7 +23,6 @@ Please describe the tests that you ran to verify your changes. Provide instructi Answer the following question based on these examples of changes that would require a Contrib Repo Change: - [The OTel specification](https://github.com/open-telemetry/opentelemetry-specification) has changed which prompted this PR to update the method interfaces of `opentelemetry-api/` or `opentelemetry-sdk/` -- The method interfaces of `opentelemetry-instrumentation/` have changed - The method interfaces of `test/util` have changed - Scripts in `scripts/` that were copied over to the Contrib repo have changed - Configuration files that were copied over to the Contrib repo have changed (when consistency between repositories is applicable) such as in diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 99ea5b18272..732d78aeb55 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: 793ddb4ed638231f387eef2e11207ffb18c6682a + CONTRIB_REPO_SHA: bcd337f74db582684e29fd5e0a9a2de591566c9b jobs: build: diff --git a/CHANGELOG.md b/CHANGELOG.md index 56f1751856d..87a1781ad0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.1.0...HEAD) +### Removed +- Moved `opentelemetry-instrumentation` to contrib repository + ([#1797](https://github.com/open-telemetry/opentelemetry-python/pull/1797)) + ## [1.1.0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.1.0) - 2021-04-20 ### Added diff --git a/docs-requirements.txt b/docs-requirements.txt index bda30280404..f802674afd0 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -7,9 +7,8 @@ sphinx-autodoc-typehints ./opentelemetry-api ./opentelemetry-semantic-conventions ./opentelemetry-sdk -./opentelemetry-instrumentation -# Required by ext packages +# Required by instrumentation and exporter packages asgiref~=3.0 asyncpg>=0.12.0 ddtrace>=0.34.0 diff --git a/docs/conf.py b/docs/conf.py index 0f1a69503f0..38a26e323fd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,11 +23,6 @@ settings.configure() - -source_dirs = [ - os.path.abspath("../opentelemetry-instrumentation/src/"), -] - exp = "../exporter" exp_dirs = [ os.path.abspath("/".join(["../exporter", f, "src"])) @@ -42,7 +37,7 @@ if isdir(join(shim, f)) ] -sys.path[:0] = source_dirs + exp_dirs + shim_dirs +sys.path[:0] = exp_dirs + shim_dirs # -- Project information ----------------------------------------------------- diff --git a/eachdist.ini b/eachdist.ini index ded3a5d8c12..d2093491b9c 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -7,13 +7,10 @@ ignore= sortfirst= opentelemetry-api opentelemetry-sdk - opentelemetry-instrumentation opentelemetry-proto opentelemetry-distro tests/util - instrumentation/* exporter/* - ext/* [lintroots] extraroots=examples/*,scripts/ diff --git a/opentelemetry-distro/setup.cfg b/opentelemetry-distro/setup.cfg index 112838fc9f5..2249765ade2 100644 --- a/opentelemetry-distro/setup.cfg +++ b/opentelemetry-distro/setup.cfg @@ -41,6 +41,7 @@ zip_safe = False include_package_data = True install_requires = opentelemetry-api == 1.2.0.dev0 + opentelemetry-instrumentation == 0.21.dev0 opentelemetry-sdk == 1.2.0.dev0 [options.packages.find] diff --git a/opentelemetry-distro/src/opentelemetry/distro/__init__.py b/opentelemetry-distro/src/opentelemetry/distro/__init__.py index d60bbd208ee..ba86e0e247d 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/__init__.py +++ b/opentelemetry-distro/src/opentelemetry/distro/__init__.py @@ -147,6 +147,8 @@ def _initialize_components(): class Configurator(BaseConfigurator): + + # pylint: disable=no-self-use def _configure(self, **kwargs): _initialize_components() @@ -157,5 +159,6 @@ class OpenTelemetryDistro(BaseDistro): configuration out of the box. """ + # pylint: disable=no-self-use def _configure(self, **kwargs): os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp_proto_grpc_span") diff --git a/opentelemetry-instrumentation/MANIFEST.in b/opentelemetry-instrumentation/MANIFEST.in deleted file mode 100644 index 191b7d19592..00000000000 --- 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 6f74d2232f7..00000000000 --- 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 8178cc8a132..00000000000 --- 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/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.2.0.dev0 - 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 d4f84f738ba..00000000000 --- a/opentelemetry-instrumentation/setup.py +++ /dev/null @@ -1,29 +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 f08b0b144e7..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py +++ /dev/null @@ -1,118 +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( - "-s", - "--service-name", - required=False, - help=""" - The service name that should be passed to a trace exporter. - """, - ) - - 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 10c8faf899c..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py +++ /dev/null @@ -1,109 +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, -) - -logger = getLogger(__file__) - - -def _load_distros(): - for entry_point in iter_entry_points("opentelemetry_distro"): - try: - entry_point.load()().configure() # type: ignore - logger.debug("Distribution %s configured", entry_point.name) - except Exception as exc: # pylint: disable=broad-except - logger.exception( - "Distribution %s configuration failed", entry_point.name - ) - raise exc - - -def _load_instrumentors(): - 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"): - try: - if entry_point.name in package_to_exclude: - logger.debug( - "Instrumentation skipped for library %s", entry_point.name - ) - continue - entry_point.load()().instrument() # type: ignore - 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: - _load_distros() - _load_configurators() - _load_instrumentors() - 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 46d05a7c8f3..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ /dev/null @@ -1,252 +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 pkgutil -import subprocess -import sys -from logging import getLogger - -from opentelemetry.instrumentation.version import __version__ as version - -logger = getLogger(__file__) - - -# A mapping of "target library" to "desired instrumentor path/versioned package -# name". Used as part of the `opentelemetry-bootstrap` command which looks at -# libraries used by the application that is to be instrumented, and handles -# automatically installing the appropriate instrumentations for that app. -# This helps for those who prefer to turn on as much instrumentation as -# possible, and don't want to go through the manual process of combing through -# the libraries their application uses to figure which one can be -# instrumented. -# NOTE: system-metrics is not to be included. -def all_instrumentations(): - pkg_instrumentation_map = { - "aiohttp-client": "opentelemetry-instrumentation-aiohttp-client", - "aiopg": "opentelemetry-instrumentation-aiopg", - "asyncpg": "opentelemetry-instrumentation-asyncpg", - "boto": "opentelemetry-instrumentation-boto", - "botocore": "opentelemetry-instrumentation-botocore", - "celery": "opentelemetry-instrumentation-celery", - "dbapi": "opentelemetry-instrumentation-dbapi", - "django": "opentelemetry-instrumentation-django", - "elasticsearch": "opentelemetry-instrumentation-elasticsearch", - "falcon": "opentelemetry-instrumentation-falcon", - "fastapi": "opentelemetry-instrumentation-fastapi", - "flask": "opentelemetry-instrumentation-flask", - "grpc": "opentelemetry-instrumentation-grpc", - "jinja2": "opentelemetry-instrumentation-jinja2", - "mysql": "opentelemetry-instrumentation-mysql", - "psycopg2": "opentelemetry-instrumentation-psycopg2", - "pymemcache": "opentelemetry-instrumentation-pymemcache", - "pymongo": "opentelemetry-instrumentation-pymongo", - "pymysql": "opentelemetry-instrumentation-pymysql", - "pyramid": "opentelemetry-instrumentation-pyramid", - "redis": "opentelemetry-instrumentation-redis", - "requests": "opentelemetry-instrumentation-requests", - "sklearn": "opentelemetry-instrumentation-sklearn", - "sqlalchemy": "opentelemetry-instrumentation-sqlalchemy", - "sqlite3": "opentelemetry-instrumentation-sqlite3", - "starlette": "opentelemetry-instrumentation-starlette", - "tornado": "opentelemetry-instrumentation-tornado", - "urllib": "opentelemetry-instrumentation-urllib", - } - for pkg, instrumentation in pkg_instrumentation_map.items(): - pkg_instrumentation_map[pkg] = "{0}=={1}".format( - instrumentation, version - ) - return pkg_instrumentation_map - - -instrumentations = all_instrumentations() - -# relevant instrumentors and tracers to uninstall and check for conflicts for target libraries -libraries = { - "aiohttp-client": ("opentelemetry-instrumentation-aiohttp-client",), - "aiopg": ("opentelemetry-instrumentation-aiopg",), - "asyncpg": ("opentelemetry-instrumentation-asyncpg",), - "boto": ("opentelemetry-instrumentation-boto",), - "botocore": ("opentelemetry-instrumentation-botocore",), - "celery": ("opentelemetry-instrumentation-celery",), - "dbapi": ("opentelemetry-instrumentation-dbapi",), - "django": ("opentelemetry-instrumentation-django",), - "elasticsearch": ("opentelemetry-instrumentation-elasticsearch",), - "falcon": ("opentelemetry-instrumentation-falcon",), - "fastapi": ("opentelemetry-instrumentation-fastapi",), - "flask": ("opentelemetry-instrumentation-flask",), - "grpc": ("opentelemetry-instrumentation-grpc",), - "jinja2": ("opentelemetry-instrumentation-jinja2",), - "mysql": ("opentelemetry-instrumentation-mysql",), - "psycopg2": ("opentelemetry-instrumentation-psycopg2",), - "pymemcache": ("opentelemetry-instrumentation-pymemcache",), - "pymongo": ("opentelemetry-instrumentation-pymongo",), - "pymysql": ("opentelemetry-instrumentation-pymysql",), - "pyramid": ("opentelemetry-instrumentation-pyramid",), - "redis": ("opentelemetry-instrumentation-redis",), - "requests": ("opentelemetry-instrumentation-requests",), - "sklearn": ("opentelemetry-instrumentation-sklearn",), - "sqlalchemy": ("opentelemetry-instrumentation-sqlalchemy",), - "sqlite3": ("opentelemetry-instrumentation-sqlite3",), - "starlette": ("opentelemetry-instrumentation-starlette",), - "tornado": ("opentelemetry-instrumentation-tornado",), - "urllib": ("opentelemetry-instrumentation-urllib",), -} - - -def _install_package(library, instrumentation): - """ - Ensures that desired version is installed w/o upgrading its dependencies - by uninstalling where necessary (if `target` is not provided). - - - OpenTelemetry auto-instrumentation packages often have traced libraries - as instrumentation dependency (e.g. flask for - opentelemetry-instrumentation-flask), so using -I on library could cause - likely undesired Flask upgrade.Using --no-dependencies alone would leave - potential for nonfunctional installations. - """ - pip_list = _sys_pip_freeze() - for package in libraries[library]: - if "{}==".format(package).lower() in pip_list: - logger.info( - "Existing %s installation detected. Uninstalling.", package - ) - _sys_pip_uninstall(package) - _sys_pip_install(instrumentation) - - -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_freeze(): - return ( - subprocess.check_output([sys.executable, "-m", "pip", "freeze"]) - .decode() - .lower() - ) - - -@_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, - ] - ) - - -@_syscall -def _sys_pip_uninstall(package): - subprocess.check_call( - [sys.executable, "-m", "pip", "uninstall", "-y", 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. - """ - 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(library): - return library in sys.modules or pkgutil.find_loader(library) is not None - - -def _find_installed_libraries(): - return {k: v for k, v in instrumentations.items() if _is_installed(k)} - - -def _run_requirements(packages): - print("\n".join(packages.values()), end="") - - -def _run_install(packages): - for pkg, inst in packages.items(): - _install_package(pkg, inst) - - _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(_find_installed_libraries()) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/configurator.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/configurator.py deleted file mode 100644 index 3efa71e89e9..00000000000 --- 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/distro.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py deleted file mode 100644 index 63cacf1f6d4..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/distro.py +++ /dev/null @@ -1,47 +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 - -_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) - - -__all__ = ["BaseDistro"] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py deleted file mode 100644 index 8cd77a8a5b7..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py +++ /dev/null @@ -1,94 +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 - -_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 = False - - def __new__(cls, *args, **kwargs): - - if cls._instance is None: - cls._instance = object.__new__(cls, *args, **kwargs) - - return cls._instance - - @abstractmethod - def _instrument(self, **kwargs): - """Instrument the library""" - - @abstractmethod - def _uninstrument(self, **kwargs): - """Uninstrument the library""" - - 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 not self._is_instrumented: - result = self._instrument(**kwargs) - self._is_instrumented = True - return result - - _LOG.warning("Attempting to instrument while already instrumented") - - return None - - def uninstrument(self, **kwargs): - """Uninstrument the library - - See ``BaseInstrumentor.instrument`` for more information regarding the - usage of ``kwargs``. - """ - - if self._is_instrumented: - result = self._uninstrument(**kwargs) - self._is_instrumented = 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 2fb246c9d95..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/propagators.py +++ /dev/null @@ -1,128 +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 - -import opentelemetry.trace as 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 e69de29bb2d..00000000000 diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py deleted file mode 100644 index dec070570fd..00000000000 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ /dev/null @@ -1,62 +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.trace import StatusCode - - -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 2b081752666..00000000000 --- 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.21.dev0" diff --git a/opentelemetry-instrumentation/tests/__init__.py b/opentelemetry-instrumentation/tests/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/opentelemetry-instrumentation/tests/test_bootstrap.py b/opentelemetry-instrumentation/tests/test_bootstrap.py deleted file mode 100644 index de978eb6d58..00000000000 --- a/opentelemetry-instrumentation/tests/test_bootstrap.py +++ /dev/null @@ -1,128 +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 functools import reduce -from io import StringIO -from random import sample -from unittest import TestCase -from unittest.mock import call, patch - -from opentelemetry.instrumentation import bootstrap - - -def sample_packages(packages, rate): - sampled = sample( - list(packages), - int(len(packages) * rate), - ) - return {k: v for k, v in packages.items() if k in sampled} - - -class TestBootstrap(TestCase): - - installed_libraries = {} - installed_instrumentations = {} - - @classmethod - def setUpClass(cls): - # select random 60% of instrumentations - cls.installed_libraries = sample_packages( - bootstrap.instrumentations, 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, - ) - - pip_freeze_output = [] - for inst in cls.installed_instrumentations.values(): - inst = inst.replace(">=", "==") - if "==" not in inst: - inst = "{}==x.y".format(inst) - pip_freeze_output.append(inst) - - cls.pip_freeze_patcher = patch( - "opentelemetry.instrumentation.bootstrap._sys_pip_freeze", - return_value="\n".join(pip_freeze_output), - ) - cls.pip_install_patcher = patch( - "opentelemetry.instrumentation.bootstrap._sys_pip_install", - ) - cls.pip_uninstall_patcher = patch( - "opentelemetry.instrumentation.bootstrap._sys_pip_uninstall", - ) - cls.pip_check_patcher = patch( - "opentelemetry.instrumentation.bootstrap._pip_check", - ) - - cls.pkg_patcher.start() - cls.mock_pip_freeze = cls.pip_freeze_patcher.start() - cls.mock_pip_install = cls.pip_install_patcher.start() - cls.mock_pip_uninstall = cls.pip_uninstall_patcher.start() - cls.mock_pip_check = cls.pip_check_patcher.start() - - @classmethod - def tearDownClass(cls): - cls.pip_check_patcher.start() - cls.pip_uninstall_patcher.start() - cls.pip_install_patcher.start() - cls.pip_freeze_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.values()), - ) - - @patch("sys.argv", ["bootstrap", "-a", "install"]) - def test_run_cmd_install(self): - bootstrap.run() - - self.assertEqual( - self.mock_pip_freeze.call_count, len(self.installed_libraries) - ) - - to_uninstall = reduce( - lambda x, y: x + y, - [ - pkgs - for lib, pkgs in bootstrap.libraries.items() - if lib in self.installed_instrumentations - ], - ) - self.mock_pip_uninstall.assert_has_calls( - [call(i) for i in to_uninstall], any_order=True - ) - - self.mock_pip_install.assert_has_calls( - [call(i) for i in self.installed_libraries.values()], - any_order=True, - ) - self.assertEqual(self.mock_pip_check.call_count, 1) diff --git a/opentelemetry-instrumentation/tests/test_instrumentor.py b/opentelemetry-instrumentation/tests/test_instrumentor.py deleted file mode 100644 index 19104a3246d..00000000000 --- a/opentelemetry-instrumentation/tests/test_instrumentor.py +++ /dev/null @@ -1,47 +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 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 62461aafa97..00000000000 --- 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 01bd86ed32f..00000000000 --- 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 e5246335c9f..00000000000 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ /dev/null @@ -1,57 +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) diff --git a/scripts/build.sh b/scripts/build.sh index 2f40f1a0034..8134769775c 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -16,7 +16,7 @@ DISTDIR=dist mkdir -p $DISTDIR rm -rf $DISTDIR/* - for d in opentelemetry-api/ opentelemetry-sdk/ opentelemetry-instrumentation/ opentelemetry-proto/ opentelemetry-distro/ opentelemetry-semantic-conventions/ exporter/*/ shim/*/ propagator/*/; do + for d in opentelemetry-api/ opentelemetry-sdk/ opentelemetry-proto/ opentelemetry-distro/ opentelemetry-semantic-conventions/ exporter/*/ shim/*/ propagator/*/; do ( echo "building $d" cd "$d" diff --git a/shim/opentelemetry-opentracing-shim/setup.cfg b/shim/opentelemetry-opentracing-shim/setup.cfg index 30f33afba72..22b1b7c1096 100644 --- a/shim/opentelemetry-opentracing-shim/setup.cfg +++ b/shim/opentelemetry-opentracing-shim/setup.cfg @@ -19,7 +19,7 @@ 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/tree/main/instrumentation/opentelemetry-instrumentation-opentracing-shim +url = https://github.com/open-telemetry/opentelemetry-python/tree/main/shim/opentelemetry-opentracing-shim platforms = any license = Apache-2.0 classifiers = diff --git a/tox.ini b/tox.ini index 96d756c45e3..f0ee49e971b 100644 --- a/tox.ini +++ b/tox.ini @@ -16,10 +16,6 @@ envlist = py3{6,7,8,9}-test-core-sdk pypy3-test-core-sdk - ; opentelemetry-instrumentation - py3{6,7,8,9}-test-core-instrumentation - pypy3-test-core-instrumentation - ; opentelemetry-semantic-conventions py3{6,7,8,9}-test-semantic-conventions pypy3-test-semantic-conventions @@ -99,7 +95,6 @@ changedir = test-core-sdk: opentelemetry-sdk/tests test-core-proto: opentelemetry-proto/tests test-semantic-conventions: opentelemetry-semantic-conventions/tests - test-core-instrumentation: opentelemetry-instrumentation/tests test-core-getting-started: docs/getting_started/tests test-core-opentracing-shim: shim/opentelemetry-opentracing-shim/tests test-core-distro: opentelemetry-distro/tests @@ -122,13 +117,12 @@ commands_pre = py3{6,7,8,9}: 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 {toxinidir}/opentelemetry-api {toxinidir}/opentelemetry-semantic-conventions {toxinidir}/opentelemetry-instrumentation {toxinidir}/opentelemetry-sdk {toxinidir}/tests/util + test: pip install {toxinidir}/opentelemetry-api {toxinidir}/opentelemetry-semantic-conventions {toxinidir}/opentelemetry-sdk {toxinidir}/tests/util test-core-proto: pip install {toxinidir}/opentelemetry-proto - distro: pip install {toxinidir}/opentelemetry-distro {toxinidir}/opentelemetry-distro - instrumentation: pip install {toxinidir}/opentelemetry-instrumentation + distro: pip install {toxinidir}/opentelemetry-python-contrib/opentelemetry-instrumentation {toxinidir}/opentelemetry-distro - getting-started: pip install -e {toxinidir}/opentelemetry-instrumentation -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-requests {toxinidir}/opentelemetry-python-contrib/util/opentelemetry-util-http -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-wsgi -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-flask + getting-started: pip install -e {toxinidir}/opentelemetry-python-contrib/opentelemetry-instrumentation -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-requests {toxinidir}/opentelemetry-python-contrib/util/opentelemetry-util-http -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-wsgi -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-flask opencensus: pip install {toxinidir}/exporter/opentelemetry-exporter-opencensus @@ -196,7 +190,6 @@ deps = commands_pre = python -m pip install -e {toxinidir}/opentelemetry-api[test] python -m pip install -e {toxinidir}/opentelemetry-semantic-conventions[test] - python -m pip install -e {toxinidir}/opentelemetry-instrumentation[test] python -m pip install -e {toxinidir}/opentelemetry-sdk[test] python -m pip install -e {toxinidir}/opentelemetry-proto[test] python -m pip install -e {toxinidir}/tests/util[test] @@ -212,6 +205,7 @@ commands_pre = python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-zipkin[test] python -m pip install -e {toxinidir}/propagator/opentelemetry-propagator-b3[test] python -m pip install -e {toxinidir}/propagator/opentelemetry-propagator-jaeger[test] + python -m pip install {toxinidir}/opentelemetry-python-contrib/opentelemetry-instrumentation python -m pip install -e {toxinidir}/opentelemetry-distro[test] commands = @@ -225,6 +219,9 @@ deps = changedir = docs +commands_pre = + python -m pip install {toxinidir}/opentelemetry-python-contrib/opentelemetry-instrumentation + commands = sphinx-build -E -a -W -b html -T . _build/html @@ -239,8 +236,8 @@ deps = commands_pre = pip install -e {toxinidir}/opentelemetry-api \ - -e {toxinidir}/opentelemetry-instrumentation \ -e {toxinidir}/opentelemetry-sdk \ + -e {toxinidir}/opentelemetry-python-contrib/opentelemetry-instrumentation \ -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-requests \ -e {toxinidir}/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-wsgi \ -e {toxinidir}/opentelemetry-python-contrib/util/opentelemetry-util-http @@ -259,7 +256,7 @@ changedir = commands_pre = pip install -e {toxinidir}/opentelemetry-api \ -e {toxinidir}/opentelemetry-semantic-conventions \ - -e {toxinidir}/opentelemetry-instrumentation \ + -e {toxinidir}/opentelemetry-python-contrib/opentelemetry-instrumentation \ -e {toxinidir}/opentelemetry-sdk \ -e {toxinidir}/tests/util \ -e {toxinidir}/exporter/opentelemetry-exporter-opencensus \