diff --git a/.pylintrc b/.pylintrc index 2a2ad87040..22720cf232 100644 --- a/.pylintrc +++ b/.pylintrc @@ -79,6 +79,7 @@ disable=missing-docstring, super-init-not-called, # temp-pylint-upgrade invalid-overridden-method, # temp-pylint-upgrade missing-module-docstring, # temp-pylint-upgrade + import-error, # needed as a workaround as reported here: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/290 # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/instrumentation/opentelemetry-instrumentation-django/setup.cfg b/instrumentation/opentelemetry-instrumentation-django/setup.cfg index 30c2c3359b..2e0f1354b5 100644 --- a/instrumentation/opentelemetry-instrumentation-django/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-django/setup.cfg @@ -40,7 +40,7 @@ package_dir= packages=find_namespace: install_requires = django >= 1.10 - opentelemetry-instrumentation-wsgi == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 opentelemetry-instrumentation == 0.18.dev0 opentelemetry-api == 0.18.dev0 diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py index 0f0eed11a4..64be5c53f0 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py @@ -13,9 +13,6 @@ # limitations under the License. from logging import getLogger -from os import environ -from re import compile as re_compile -from re import search from time import time from django.conf import settings @@ -23,13 +20,14 @@ from opentelemetry.context import attach, detach from opentelemetry.instrumentation.django.version import __version__ from opentelemetry.instrumentation.utils import extract_attributes_from_object -from opentelemetry.instrumentation.wsgi import ( +from opentelemetry.propagators import extract +from opentelemetry.trace import SpanKind, get_tracer +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs +from opentelemetry.util.http.wsgi import ( add_response_attributes, carrier_getter, collect_request_attributes, ) -from opentelemetry.propagators import extract -from opentelemetry.trace import SpanKind, get_tracer try: from django.core.urlresolvers import ( # pylint: disable=no-name-in-module @@ -53,46 +51,6 @@ ] -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -_root = r"OTEL_PYTHON_{}" - - -def _get_traced_request_attrs(): - traced_request_attrs = environ.get( - _root.format("DJANGO_TRACED_REQUEST_ATTRS"), [] - ) - - if traced_request_attrs: - traced_request_attrs = [ - traced_request_attr.strip() - for traced_request_attr in traced_request_attrs.split(",") - ] - - return traced_request_attrs - - -def _get_excluded_urls(): - excluded_urls = environ.get(_root.format("DJANGO_EXCLUDED_URLS"), []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - - class _DjangoMiddleware(MiddlewareMixin): """Django Middleware for OpenTelemetry""" @@ -103,8 +61,8 @@ class _DjangoMiddleware(MiddlewareMixin): _environ_span_key = "opentelemetry-instrumentor-django.span_key" _environ_exception_key = "opentelemetry-instrumentor-django.exception_key" - _traced_request_attrs = _get_traced_request_attrs() - _excluded_urls = _get_excluded_urls() + _traced_request_attrs = get_traced_request_attrs("DJANGO") + _excluded_urls = get_excluded_urls("DJANGO") @staticmethod def _get_span_name(request): diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index fe3f25255c..21cbf53346 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -22,15 +22,12 @@ from django.test.utils import setup_test_environment, teardown_test_environment from opentelemetry.instrumentation.django import DjangoInstrumentor -from opentelemetry.instrumentation.django.middleware import ( - _get_excluded_urls, - _get_traced_request_attrs, -) from opentelemetry.sdk.util import get_dict_as_key from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.trace import SpanKind from opentelemetry.trace.status import StatusCode +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs # pylint: disable=import-error from .views import ( @@ -77,11 +74,11 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.django.middleware._DjangoMiddleware._excluded_urls", - _get_excluded_urls(), + get_excluded_urls("DJANGO"), ) self.traced_patch = patch( "opentelemetry.instrumentation.django.middleware._DjangoMiddleware._traced_request_attrs", - _get_traced_request_attrs(), + get_traced_request_attrs("DJANGO"), ) self.exclude_patch.start() self.traced_patch.start() diff --git a/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg b/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg index a873efe4df..2cd471f13b 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg @@ -41,7 +41,7 @@ package_dir= packages=find_namespace: install_requires = falcon ~= 2.0 - opentelemetry-instrumentation-wsgi == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 opentelemetry-instrumentation == 0.18.dev0 opentelemetry-api == 0.18.dev0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index a3ffb0d5fa..51ecf0d645 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -14,7 +14,7 @@ """ This library builds on the OpenTelemetry WSGI middleware to track web requests -in Falcon applications. In addition to opentelemetry-instrumentation-wsgi, +in Falcon applications. In addition to opentelemetry-util-http, it supports falcon-specific features such as: * The Falcon resource and method name is used as the Span name. @@ -44,14 +44,11 @@ def on_get(self, req, resp): """ from logging import getLogger -from os import environ -from re import compile as re_compile -from re import search from sys import exc_info import falcon -import opentelemetry.instrumentation.wsgi as otel_wsgi +import opentelemetry.util.http.wsgi as otel_wsgi from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.falcon.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -61,6 +58,7 @@ def on_get(self, req, resp): ) from opentelemetry.trace.status import Status from opentelemetry.util import time_ns +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs _logger = getLogger(__name__) @@ -71,48 +69,8 @@ def on_get(self, req, resp): _ENVIRON_EXC = "opentelemetry-falcon.exc" -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -_root = r"OTEL_PYTHON_{}" - - -def _get_traced_request_attrs(): - traced_request_attrs = environ.get( - _root.format("FALCON_TRACED_REQUEST_ATTRS"), [] - ) - - if traced_request_attrs: - traced_request_attrs = [ - traced_request_attr.strip() - for traced_request_attr in traced_request_attrs.split(",") - ] - - return traced_request_attrs - - -def _get_excluded_urls(): - excluded_urls = environ.get(_root.format("FALCON_EXCLUDED_URLS"), []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - - -_excluded_urls = _get_excluded_urls() -_traced_request_attrs = _get_traced_request_attrs() +_excluded_urls = get_excluded_urls("FALCON") +_traced_request_attrs = get_traced_request_attrs("FALCON") class FalconInstrumentor(BaseInstrumentor): diff --git a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py index 0b4f52fda2..8a4c1912a2 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py @@ -16,13 +16,10 @@ from falcon import testing -from opentelemetry.instrumentation.falcon import ( - FalconInstrumentor, - _get_excluded_urls, - _get_traced_request_attrs, -) +from opentelemetry.instrumentation.falcon import FalconInstrumentor from opentelemetry.test.test_base import TestBase from opentelemetry.trace.status import StatusCode +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs from .app import make_app @@ -43,13 +40,15 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.falcon._excluded_urls", - _get_excluded_urls(), + get_excluded_urls("FALCON"), ) middleware = self.app._middleware[0][ # pylint:disable=W0212 0 ].__self__ self.traced_patch = patch.object( - middleware, "_traced_request_attrs", _get_traced_request_attrs(), + middleware, + "_traced_request_attrs", + get_traced_request_attrs("FALCON"), ) self.exclude_patch.start() self.traced_patch.start() diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg b/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg index f6d362c176..22181de466 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg @@ -39,7 +39,7 @@ package_dir= packages=find_namespace: install_requires = opentelemetry-api == 0.18.dev0 - opentelemetry-instrumentation-asgi == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 [options.entry_points] opentelemetry_instrumentor = diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py index ad3e3eae6c..7c6429ba32 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -12,42 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -from os import environ -from re import compile as re_compile -from re import search - import fastapi from starlette.routing import Match -from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware -from opentelemetry.instrumentation.fastapi.version import __version__ # noqa from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.util.http import get_excluded_urls +from opentelemetry.util.http.asgi import OpenTelemetryMiddleware - -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -def _get_excluded_urls(): - excluded_urls = environ.get("OTEL_PYTHON_FASTAPI_EXCLUDED_URLS", []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - - -_excluded_urls = _get_excluded_urls() +_excluded_urls = get_excluded_urls("FASTAPI") class FastAPIInstrumentor(BaseInstrumentor): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 13d90e410f..fe6c27928a 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -20,6 +20,7 @@ import opentelemetry.instrumentation.fastapi as otel_fastapi from opentelemetry.test.test_base import TestBase +from opentelemetry.util.http import get_excluded_urls class TestFastAPIManualInstrumentation(TestBase): @@ -37,7 +38,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.fastapi._excluded_urls", - otel_fastapi._get_excluded_urls(), + get_excluded_urls("FASTAPI"), ) self.exclude_patch.start() self._instrumentor = otel_fastapi.FastAPIInstrumentor() diff --git a/instrumentation/opentelemetry-instrumentation-flask/setup.cfg b/instrumentation/opentelemetry-instrumentation-flask/setup.cfg index 3a25fde29c..95198e9431 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-flask/setup.cfg @@ -40,7 +40,7 @@ package_dir= packages=find_namespace: install_requires = flask ~= 1.0 - opentelemetry-instrumentation-wsgi == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 opentelemetry-instrumentation == 0.18.dev0 opentelemetry-api == 0.18.dev0 diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index e0ced69599..1f8adb3d00 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -17,8 +17,8 @@ """ This library builds on the OpenTelemetry WSGI middleware to track web requests -in Flask applications. In addition to opentelemetry-instrumentation-wsgi, it supports -flask-specific features such as: +in Flask applications. In addition to opentelemetry-util-http, it +supports Flask-specific features such as: * The Flask url rule pattern is used as the Span name. * The ``http.route`` Span attribute is set so that one can see which URL rule @@ -48,17 +48,15 @@ def hello(): """ from logging import getLogger -from os import environ -from re import compile as re_compile -from re import search import flask -import opentelemetry.instrumentation.wsgi as otel_wsgi +import opentelemetry.util.http.wsgi as otel_wsgi from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.flask.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.util import time_ns +from opentelemetry.util.http import get_excluded_urls _logger = getLogger(__name__) @@ -68,30 +66,7 @@ def hello(): _ENVIRON_TOKEN = "opentelemetry-flask.token" -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -def _get_excluded_urls(): - excluded_urls = environ.get("OTEL_PYTHON_FLASK_EXCLUDED_URLS", []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - - -_excluded_urls = _get_excluded_urls() +_excluded_urls = get_excluded_urls("FLASK") def get_default_span_name(): diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 9ea43b9997..4b9eead82b 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -17,12 +17,10 @@ from flask import Flask, request from opentelemetry import trace -from opentelemetry.instrumentation.flask import ( - FlaskInstrumentor, - _get_excluded_urls, -) +from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase +from opentelemetry.util.http import get_excluded_urls # pylint: disable=import-error from .base_test import InstrumentationTest @@ -65,7 +63,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.flask._excluded_urls", - _get_excluded_urls(), + get_excluded_urls("FLASK"), ) self.exclude_patch.start() diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/_server.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/_server.py index a4e1c266b8..1f4f205417 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/_server.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/_server.py @@ -22,6 +22,9 @@ class TestServer(test_server_pb2_grpc.GRPCTestServerServicer): + # pylint: disable=invalid-name + # pylint: disable=no-self-use + def SimpleMethod(self, request, context): if request.request_data == "error": context.set_code(grpc.StatusCode.INVALID_ARGUMENT) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py index 0eaeebbc23..f272a90240 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py @@ -13,7 +13,9 @@ # limitations under the License. import grpc -from tests.protobuf import test_server_pb2_grpc +from tests.protobuf import ( # pylint: disable=no-name-in-module + test_server_pb2_grpc, +) import opentelemetry.instrumentation.grpc from opentelemetry import trace diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg b/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg index 97c970ddde..1c7c676fc4 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg @@ -42,7 +42,7 @@ install_requires = pyramid >= 1.7 opentelemetry-instrumentation == 0.18.dev0 opentelemetry-api == 0.18.dev0 - opentelemetry-instrumentation-wsgi == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 wrapt >= 1.0.0, < 2.0.0 [options.extras_require] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index dd6a26755b..0aa8a02371 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -1,17 +1,15 @@ from logging import getLogger -from os import environ -from re import compile as re_compile -from re import search from pyramid.events import BeforeTraversal from pyramid.httpexceptions import HTTPException from pyramid.settings import asbool from pyramid.tweens import EXCVIEW -import opentelemetry.instrumentation.wsgi as otel_wsgi +import opentelemetry.util.http.wsgi as otel_wsgi from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.pyramid.version import __version__ from opentelemetry.util import time_ns +from opentelemetry.util.http import get_excluded_urls TWEEN_NAME = "opentelemetry.instrumentation.pyramid.trace_tween_factory" SETTING_TRACE_ENABLED = "opentelemetry-pyramid.trace_enabled" @@ -25,30 +23,7 @@ _logger = getLogger(__name__) -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -def _get_excluded_urls(): - excluded_urls = environ.get("OTEL_PYTHON_PYRAMID_EXCLUDED_URLS", []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - - -_excluded_urls = _get_excluded_urls() +_excluded_urls = get_excluded_urls("PYRAMID") def includeme(config): diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py index 6dfa05fb0c..4f0fa96e2b 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py @@ -18,9 +18,9 @@ from opentelemetry import trace from opentelemetry.instrumentation.pyramid import PyramidInstrumentor -from opentelemetry.instrumentation.pyramid.callbacks import _get_excluded_urls from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase +from opentelemetry.util.http import get_excluded_urls # pylint: disable=import-error from .pyramid_base_test import InstrumentationTest @@ -63,7 +63,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.pyramid.callbacks._excluded_urls", - _get_excluded_urls(), + get_excluded_urls("PYRAMID"), ) self.exclude_patch.start() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg b/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg index 2ba3f185ec..d2f17af803 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg @@ -39,7 +39,7 @@ package_dir= packages=find_namespace: install_requires = opentelemetry-api == 0.18.dev0 - opentelemetry-instrumentation-asgi == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 [options.entry_points] opentelemetry_instrumentor = diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py index cff9b2d5cc..f222225e76 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -12,42 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -from os import environ -from re import compile as re_compile -from re import search - from starlette import applications from starlette.routing import Match -from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.starlette.version import __version__ # noqa - - -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -def _get_excluded_urls(): - excluded_urls = environ.get("OTEL_PYTHON_STARLETTE_EXCLUDED_URLS", []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - +from opentelemetry.util.http import get_excluded_urls +from opentelemetry.util.http.asgi import OpenTelemetryMiddleware -_excluded_urls = _get_excluded_urls() +_excluded_urls = get_excluded_urls("STARLETTE") class StarletteInstrumentor(BaseInstrumentor): diff --git a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py index 3df7896d12..56116c5a06 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -22,6 +22,7 @@ import opentelemetry.instrumentation.starlette as otel_starlette from opentelemetry.test.test_base import TestBase +from opentelemetry.util.http import get_excluded_urls class TestStarletteManualInstrumentation(TestBase): @@ -39,7 +40,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.starlette._excluded_urls", - otel_starlette._get_excluded_urls(), + get_excluded_urls("STARLETTE"), ) self.exclude_patch.start() self._instrumentor = otel_starlette.StarletteInstrumentor() diff --git a/instrumentation/opentelemetry-instrumentation-tornado/setup.cfg b/instrumentation/opentelemetry-instrumentation-tornado/setup.cfg index c5b9778ad3..d077aabc20 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-tornado/setup.cfg @@ -41,6 +41,7 @@ install_requires = tornado >= 6.0 opentelemetry-instrumentation == 0.18.dev0 opentelemetry-api == 0.18.dev0 + opentelemetry-util-http == 0.18.dev0 [options.extras_require] test = diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py index fc8269b755..eda6a91ae6 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -38,9 +38,6 @@ def get(self): from collections import namedtuple from functools import partial from logging import getLogger -from os import environ -from re import compile as re_compile -from re import search import tornado.web import wrapt @@ -57,6 +54,7 @@ def get(self): from opentelemetry.trace.propagation.textmap import DictGetter from opentelemetry.trace.status import Status from opentelemetry.util import time_ns +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs from .client import fetch_async # pylint: disable=E0401 @@ -66,48 +64,8 @@ def get(self): _OTEL_PATCHED_KEY = "_otel_patched_key" -class _ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -_root = r"OTEL_PYTHON_{}" - - -def _get_traced_request_attrs(): - traced_request_attrs = environ.get( - _root.format("TORNADO_TRACED_REQUEST_ATTRS"), [] - ) - - if traced_request_attrs: - traced_request_attrs = [ - traced_request_attr.strip() - for traced_request_attr in traced_request_attrs.split(",") - ] - - return traced_request_attrs - - -def _get_excluded_urls(): - excluded_urls = environ.get(_root.format("TORNADO_EXCLUDED_URLS"), []) - - if excluded_urls: - excluded_urls = [ - excluded_url.strip() for excluded_url in excluded_urls.split(",") - ] - - return _ExcludeList(excluded_urls) - - -_excluded_urls = _get_excluded_urls() -_traced_request_attrs = _get_traced_request_attrs() +_excluded_urls = get_excluded_urls("TORNADO") +_traced_request_attrs = get_traced_request_attrs("TORNADO") carrier_getter = DictGetter() diff --git a/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py index 11eef390ee..26d4eddfa9 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py @@ -20,13 +20,12 @@ from opentelemetry import trace from opentelemetry.instrumentation.tornado import ( TornadoInstrumentor, - _get_excluded_urls, - _get_traced_request_attrs, patch_handler_class, unpatch_handler_class, ) from opentelemetry.test.test_base import TestBase from opentelemetry.trace import SpanKind +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs from .tornado_test_app import ( AsyncHandler, @@ -56,11 +55,11 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.tornado._excluded_urls", - _get_excluded_urls(), + get_excluded_urls("TORNADO"), ) self.traced_patch = patch( "opentelemetry.instrumentation.tornado._traced_request_attrs", - _get_traced_request_attrs(), + get_traced_request_attrs("TORNADO"), ) self.exclude_patch.start() self.traced_patch.start() diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/LICENSE b/instrumentation/opentelemetry-instrumentation-wsgi/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/instrumentation/opentelemetry-instrumentation-wsgi/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/MANIFEST.in b/instrumentation/opentelemetry-instrumentation-wsgi/MANIFEST.in deleted file mode 100644 index aed3e33273..0000000000 --- a/instrumentation/opentelemetry-instrumentation-wsgi/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -graft src -graft tests -global-exclude *.pyc -global-exclude *.pyo -global-exclude __pycache__/* -include CHANGELOG.md -include MANIFEST.in -include README.rst -include LICENSE diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/README.rst b/instrumentation/opentelemetry-instrumentation-wsgi/README.rst deleted file mode 100644 index c3f06bfedb..0000000000 --- a/instrumentation/opentelemetry-instrumentation-wsgi/README.rst +++ /dev/null @@ -1,26 +0,0 @@ -OpenTelemetry WSGI Middleware -============================= - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-wsgi.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-wsgi/ - - -This library provides a WSGI middleware that can be used on any WSGI framework -(such as Django / Flask) to track requests timing through OpenTelemetry. - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation-wsgi - - -References ----------- - -* `OpenTelemetry WSGI Middleware `_ -* `OpenTelemetry Project `_ -* `WSGI `_ diff --git a/tox.ini b/tox.ini index e4958aa7f9..3f095bc94e 100644 --- a/tox.ini +++ b/tox.ini @@ -94,10 +94,6 @@ envlist = py3{5,6,7,8}-test-instrumentation-pyramid pypy3-test-instrumentation-pyramid - ; opentelemetry-instrumentation-asgi - py3{5,6,7,8}-test-instrumentation-asgi - pypy3-test-instrumentation-asgi - ; opentelemetry-instrumentation-asyncpg py3{5,6,7,8}-test-instrumentation-asyncpg ; ext-asyncpg intentionally excluded from pypy3 @@ -106,10 +102,6 @@ envlist = py3{5,6,7,8}-test-instrumentation-sqlite3 pypy3-test-instrumentation-sqlite3 - ; opentelemetry-instrumentation-wsgi - py3{5,6,7,8}-test-instrumentation-wsgi - pypy3-test-instrumentation-wsgi - ; opentelemetry-instrumentation-grpc py3{5,6,7,8}-test-instrumentation-grpc @@ -138,6 +130,10 @@ envlist = py3{5,6,7,8}-test-instrumentation-tornado pypy3-test-instrumentation-tornado + ; opentelemetry-util-http + py3{5,6,7,8}-test-util-http + pypy3-test-util-http + lint docker-tests @@ -163,7 +159,6 @@ deps = changedir = test-instrumentation-aiohttp-client: instrumentation/opentelemetry-instrumentation-aiohttp-client/tests test-instrumentation-aiopg: instrumentation/opentelemetry-instrumentation-aiopg/tests - test-instrumentation-asgi: instrumentation/opentelemetry-instrumentation-asgi/tests test-instrumentation-asyncpg: instrumentation/opentelemetry-instrumentation-asyncpg/tests test-instrumentation-boto: instrumentation/opentelemetry-instrumentation-boto/tests test-instrumentation-botocore: instrumentation/opentelemetry-instrumentation-botocore/tests @@ -191,7 +186,7 @@ changedir = test-instrumentation-starlette: instrumentation/opentelemetry-instrumentation-starlette/tests test-instrumentation-system-metrics: instrumentation/opentelemetry-instrumentation-system-metrics/tests test-instrumentation-tornado: instrumentation/opentelemetry-instrumentation-tornado/tests - test-instrumentation-wsgi: instrumentation/opentelemetry-instrumentation-wsgi/tests + test-util-http: util/opentelemetry-util-http/tests test-sdkextension-aws: sdk-extension/opentelemetry-sdk-extension-aws/tests test-exporter-datadog: exporter/opentelemetry-exporter-datadog/tests @@ -210,8 +205,7 @@ commands_pre = grpc: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc[test] - wsgi,falcon,flask,django,pyramid: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi - asgi,starlette,fastapi: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi + falcon,flask,django,pyramid,starlette,fastapi,tornado: pip install {toxinidir}/util/opentelemetry-util-http asyncpg: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg @@ -233,7 +227,6 @@ commands_pre = fastapi: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-fastapi[test] mysql: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql[test] - pymemcache: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache[test] pymongo: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo[test] @@ -270,10 +263,11 @@ commands_pre = elasticsearch{2,5,6,7}: pip install {toxinidir}/opentelemetry-python-core/opentelemetry-instrumentation {toxinidir}/instrumentation/opentelemetry-instrumentation-elasticsearch[test] - aws: pip install requests {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws -; In order to get a healthy coverage report, + http: pip install {toxinidir}/util/opentelemetry-util-http + +; In order to get a health coverage report, ; we have to install packages in editable mode. coverage: python {toxinidir}/scripts/eachdist.py install --editable @@ -302,9 +296,8 @@ commands_pre = python -m pip install {toxinidir}/opentelemetry-python-core/opentelemetry-instrumentation python -m pip install {toxinidir}/opentelemetry-python-core/opentelemetry-sdk python -m pip install {toxinidir}/opentelemetry-python-core/tests/util - python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi[test] + python -m pip install {toxinidir}/util/opentelemetry-util-http python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi[test] - python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-django[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette[test] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/README.rst b/util/opentelemetry-util-http/README.rst similarity index 57% rename from instrumentation/opentelemetry-instrumentation-asgi/README.rst rename to util/opentelemetry-util-http/README.rst index 3eb8e2dda7..3ec70435d9 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/README.rst +++ b/util/opentelemetry-util-http/README.rst @@ -1,21 +1,22 @@ -OpenTelemetry ASGI Instrumentation -================================== +OpenTelemetry Util HTTP +======================= |pypi| -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-asgi.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-asgi/ +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-util-http.svg + :target: https://pypi.org/project/opentelemetry-util-http/ -This library provides a ASGI middleware that can be used on any ASGI framework -(such as Django, Starlette, FastAPI or Quart) to track requests timing through OpenTelemetry. +This library provides ASGI, WSGI middleware and other HTTP-related +functionality that is common to instrumented web frameworks (such as Django, +Starlette, FastAPI, etc.) to track requests timing through OpenTelemetry. Installation ------------ :: - pip install opentelemetry-instrumentation-asgi + pip install opentelemetry-util-http Usage (Quart) @@ -24,7 +25,7 @@ Usage (Quart) .. code-block:: python from quart import Quart - from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + from opentelemetry.util.http.asgi import OpenTelemetryMiddleware app = Quart(__name__) app.asgi_app = OpenTelemetryMiddleware(app.asgi_app) @@ -46,7 +47,7 @@ Modify the application's ``asgi.py`` file as shown below. import os from django.core.asgi import get_asgi_application - from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + from opentelemetry.util.http.asgi import OpenTelemetryMiddleware os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'asgi_example.settings') @@ -59,7 +60,7 @@ Usage (Raw ASGI) .. code-block:: python - from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + from opentelemetry.util.http.asgi import OpenTelemetryMiddleware app = ... # An ASGI application. app = OpenTelemetryMiddleware(app) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg b/util/opentelemetry-util-http/setup.cfg similarity index 90% rename from instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg rename to util/opentelemetry-util-http/setup.cfg index 8cf470ef1f..e304fea9d8 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg +++ b/util/opentelemetry-util-http/setup.cfg @@ -13,13 +13,13 @@ # limitations under the License. # [metadata] -name = opentelemetry-instrumentation-wsgi -description = WSGI Middleware for OpenTelemetry +name = opentelemetry-util-http +description = Web util for OpenTelemetry 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/master/instrumentation/opentelemetry-instrumentation-wsgi +url = https://github.com/open-telemetry/opentelemetry-python-contrib/util/opentelemetry-util-http platforms = any license = Apache-2.0 classifiers = @@ -41,6 +41,7 @@ packages=find_namespace: install_requires = opentelemetry-api == 0.18.dev0 opentelemetry-instrumentation == 0.18.dev0 + asgiref ~= 3.0 [options.extras_require] test = diff --git a/instrumentation/opentelemetry-instrumentation-asgi/setup.py b/util/opentelemetry-util-http/setup.py similarity index 91% rename from instrumentation/opentelemetry-instrumentation-asgi/setup.py rename to util/opentelemetry-util-http/setup.py index 3369352fe1..1202dd07e3 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/setup.py +++ b/util/opentelemetry-util-http/setup.py @@ -17,7 +17,7 @@ BASE_DIR = os.path.dirname(__file__) VERSION_FILENAME = os.path.join( - BASE_DIR, "src", "opentelemetry", "instrumentation", "asgi", "version.py" + BASE_DIR, "src", "opentelemetry", "util", "http", "version.py" ) PACKAGE_INFO = {} with open(VERSION_FILENAME) as f: diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py new file mode 100644 index 0000000000..068511010d --- /dev/null +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -0,0 +1,59 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from os import environ +from re import compile as re_compile +from re import search + + +class ExcludeList: + """Class to exclude certain paths (given as a list of regexes) from tracing requests""" + + def __init__(self, excluded_urls): + self._excluded_urls = excluded_urls + if self._excluded_urls: + self._regex = re_compile("|".join(excluded_urls)) + + def url_disabled(self, url: str) -> bool: + return bool(self._excluded_urls and search(self._regex, url)) + + +_root = r"OTEL_PYTHON_{}" + + +def get_traced_request_attrs(instrumentation): + traced_request_attrs = environ.get( + _root.format("{}_TRACED_REQUEST_ATTRS".format(instrumentation)), [] + ) + + if traced_request_attrs: + traced_request_attrs = [ + traced_request_attr.strip() + for traced_request_attr in traced_request_attrs.split(",") + ] + + return traced_request_attrs + + +def get_excluded_urls(instrumentation): + excluded_urls = environ.get( + _root.format("{}_EXCLUDED_URLS".format(instrumentation)), [] + ) + + if excluded_urls: + excluded_urls = [ + excluded_url.strip() for excluded_url in excluded_urls.split(",") + ] + + return ExcludeList(excluded_urls) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/__init__.py similarity index 97% rename from instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py rename to util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/__init__.py index 0947eadf08..8735404e94 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/__init__.py @@ -13,12 +13,11 @@ # limitations under the License. """ -The opentelemetry-instrumentation-asgi package provides an ASGI middleware that can be used +The opentelemetry-util-web package provides an ASGI middleware that can be used on any ASGI framework (such as Django-channels / Quart) to track requests timing through OpenTelemetry. """ -import operator import typing import urllib from functools import wraps @@ -27,10 +26,10 @@ from asgiref.compatibility import guarantee_single_callable from opentelemetry import context, propagators, trace -from opentelemetry.instrumentation.asgi.version import __version__ # noqa from opentelemetry.instrumentation.utils import http_status_to_status_code from opentelemetry.trace.propagation.textmap import DictGetter from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.util.http.asgi.version import __version__ # noqa class CarrierGetter(DictGetter): diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/version.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py rename to util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/version.py diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py rename to util/opentelemetry-util-http/src/opentelemetry/util/http/version.py diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/__init__.py similarity index 95% rename from instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py rename to util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/__init__.py index dd83203fe1..82efa3d467 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/__init__.py @@ -21,7 +21,7 @@ .. code-block:: python from flask import Flask - from opentelemetry.instrumentation.wsgi import OpenTelemetryMiddleware + from opentelemetry.util.http.wsgi import OpenTelemetryMiddleware app = Flask(__name__) app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app) @@ -42,7 +42,7 @@ def hello(): .. code-block:: python import os - from opentelemetry.instrumentation.wsgi import OpenTelemetryMiddleware + from opentelemetry.util.http.wsgi import OpenTelemetryMiddleware from django.core.wsgi import get_wsgi_application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings') @@ -60,9 +60,9 @@ def hello(): from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.utils import http_status_to_status_code -from opentelemetry.instrumentation.wsgi.version import __version__ from opentelemetry.trace.propagation.textmap import DictGetter from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.util.http.wsgi.version import __version__ _HTTP_VERSION_PREFIX = "HTTP/" @@ -234,9 +234,9 @@ def __call__(self, environ, start_response): raise -# Put this in a subfunction to not delay the call to the wrapped -# WSGI application (instrumentation should change the application -# behavior as little as possible). +# FIXME Put this in a subfunction to not delay the call to the wrapped WSGI +# application (instrumentation should change the application behavior as little +# as possible). def _end_span_after_iterating(iterable, span, tracer, token): try: with tracer.use_span(span): diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/setup.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/version.py similarity index 64% rename from instrumentation/opentelemetry-instrumentation-wsgi/setup.py rename to util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/version.py index fb4ffa7437..ab6ccdf1ba 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/setup.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/version.py @@ -11,16 +11,5 @@ # 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", "wsgi", "version.py" -) -PACKAGE_INFO = {} -with open(VERSION_FILENAME) as f: - exec(f.read(), PACKAGE_INFO) - -setuptools.setup(version=PACKAGE_INFO["__version__"]) +__version__ = "0.170" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/__init__.py b/util/opentelemetry-util-http/tests/__init__.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-asgi/tests/__init__.py rename to util/opentelemetry-util-http/tests/__init__.py diff --git a/util/opentelemetry-util-http/tests/asgi/__init__.py b/util/opentelemetry-util-http/tests/asgi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/util/opentelemetry-util-http/tests/asgi/test_asgi_middleware.py similarity index 99% rename from instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py rename to util/opentelemetry-util-http/tests/asgi/test_asgi_middleware.py index aecc06b082..f799029599 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/util/opentelemetry-util-http/tests/asgi/test_asgi_middleware.py @@ -16,7 +16,7 @@ import unittest import unittest.mock as mock -import opentelemetry.instrumentation.asgi as otel_asgi +import opentelemetry.util.http.asgi as otel_asgi from opentelemetry import trace as trace_api from opentelemetry.test.asgitestutil import ( AsgiTestBase, diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py b/util/opentelemetry-util-http/tests/wsgi/__init__.py similarity index 100% rename from instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py rename to util/opentelemetry-util-http/tests/wsgi/__init__.py diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py b/util/opentelemetry-util-http/tests/wsgi/test_getter.py similarity index 94% rename from instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py rename to util/opentelemetry-util-http/tests/wsgi/test_getter.py index 80cf6b1ecd..937f01b629 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py +++ b/util/opentelemetry-util-http/tests/wsgi/test_getter.py @@ -14,7 +14,7 @@ from unittest import TestCase -from opentelemetry.instrumentation.wsgi import CarrierGetter +from opentelemetry.util.http.wsgi import CarrierGetter class TestCarrierGetter(TestCase): diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/util/opentelemetry-util-http/tests/wsgi/test_wsgi_middleware.py similarity index 99% rename from instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py rename to util/opentelemetry-util-http/tests/wsgi/test_wsgi_middleware.py index d563ee673d..38b7c8285f 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py +++ b/util/opentelemetry-util-http/tests/wsgi/test_wsgi_middleware.py @@ -18,7 +18,7 @@ import wsgiref.util as wsgiref_util from urllib.parse import urlsplit -import opentelemetry.instrumentation.wsgi as otel_wsgi +import opentelemetry.util.http.wsgi as otel_wsgi from opentelemetry import trace as trace_api from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.trace.status import StatusCode