diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c42f4a4e4..c437b4abdc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: f3ee81243b4266729ba5196a7883ce897549aaba + CORE_REPO_SHA: 09b010cfcc85e2aa07326e9204541b80a7dd52f0 jobs: build: 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/CHANGELOG.md b/CHANGELOG.md index adfaace015..38e65c98d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update TraceState to adhere to specs ([#276](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/276)) +### Removed +- Remove Configuration + ([#285](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/285)) + ## [0.16b1](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.16b1) - 2020-11-26 ## [0.16b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.16b0) - 2020-11-25 diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index 3143b9cd75..f322eb1dd2 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -4,7 +4,6 @@ class_references= opentelemetry.trace.propagation.textmap.TextMapPropagator ; - AwsXRayFormat opentelemetry.trace.propagation.textmap.DictGetter - ; - instrumentation.asgi.CarrierGetter ; API opentelemetry.trace.propagation.textmap.Getter ; - DatadogFormat diff --git a/eachdist.ini b/eachdist.ini index 49671d8e22..65e6fc501e 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -7,6 +7,7 @@ ignore= opentelemetry-python-core sortfirst= + util/opentelemetry-util-http instrumentation/opentelemetry-instrumentation-wsgi instrumentation/opentelemetry-instrumentation-dbapi instrumentation/opentelemetry-instrumentation-asgi diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index b81b8b77f7..f52e5a4067 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -18,7 +18,6 @@ timing through OpenTelemetry. """ -import operator import typing import urllib from functools import wraps diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py index 58dee0ba7f..2eb88001ae 100644 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py @@ -84,8 +84,6 @@ def _instrument(self, **kwargs): # For exemple EC2 uses AWSQueryConnection and S3 uses # AWSAuthConnection - # FIXME should the tracer provider be accessed via Configuration - # instead? # pylint: disable=attribute-defined-outside-init self._tracer = get_tracer( __name__, __version__, kwargs.get("tracer_provider") diff --git a/instrumentation/opentelemetry-instrumentation-django/setup.cfg b/instrumentation/opentelemetry-instrumentation-django/setup.cfg index 6bb8d05ede..6528f616c0 100644 --- a/instrumentation/opentelemetry-instrumentation-django/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-django/setup.cfg @@ -40,6 +40,7 @@ package_dir= packages=find_namespace: install_requires = django >= 1.10 + opentelemetry-util-http == 0.18.dev0 opentelemetry-instrumentation-wsgi == 0.18.dev0 opentelemetry-instrumentation == 0.18.dev0 opentelemetry-api == 0.18.dev0 diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py index 26e21a1f7f..f8ed60ee55 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py @@ -13,10 +13,13 @@ # limitations under the License. from logging import getLogger +from os import environ from django.conf import settings -from opentelemetry.configuration import Configuration +from opentelemetry.instrumentation.django.environment_variables import ( + OTEL_PYTHON_DJANGO_INSTRUMENT, +) from opentelemetry.instrumentation.django.middleware import _DjangoMiddleware from opentelemetry.instrumentation.django.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -43,11 +46,7 @@ def _instrument(self, **kwargs): # FIXME this is probably a pattern that will show up in the rest of the # ext. Find a better way of implementing this. - # FIXME Probably the evaluation of strings into boolean values can be - # built inside the Configuration class itself with the magic method - # __bool__ - - if Configuration().DJANGO_INSTRUMENT is False: + if environ.get(OTEL_PYTHON_DJANGO_INSTRUMENT) == "False": return # This can not be solved, but is an inherent problem of this approach: diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/environment_variables.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/environment_variables.py new file mode 100644 index 0000000000..4972a62e93 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/environment_variables.py @@ -0,0 +1,15 @@ +# 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. + +OTEL_PYTHON_DJANGO_INSTRUMENT = "OTEL_PYTHON_DJANGO_INSTRUMENT" 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 edb585cdb4..a167cb9ab4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import time from logging import getLogger +from time import time from django.conf import settings -from opentelemetry.configuration import Configuration from opentelemetry.context import attach, detach from opentelemetry.instrumentation.django.version import __version__ from opentelemetry.instrumentation.utils import extract_attributes_from_object @@ -28,6 +27,7 @@ ) from opentelemetry.propagators import extract from opentelemetry.trace import SpanKind, get_tracer +from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs try: from django.core.urlresolvers import ( # pylint: disable=no-name-in-module @@ -61,9 +61,8 @@ class _DjangoMiddleware(MiddlewareMixin): _environ_span_key = "opentelemetry-instrumentor-django.span_key" _environ_exception_key = "opentelemetry-instrumentor-django.exception_key" - _excluded_urls = Configuration()._excluded_urls("django") - - _traced_request_attrs = Configuration()._traced_request_attrs("django") + _traced_request_attrs = get_traced_request_attrs("DJANGO") + _excluded_urls = get_excluded_urls("DJANGO") @staticmethod def _get_span_name(request): @@ -111,23 +110,23 @@ def process_request(self, request): return # pylint:disable=W0212 - request._otel_start_time = time.time() + request._otel_start_time = time() - environ = request.META + request_meta = request.META - token = attach(extract(carrier_getter, environ)) + token = attach(extract(carrier_getter, request_meta)) tracer = get_tracer(__name__, __version__) span = tracer.start_span( self._get_span_name(request), kind=SpanKind.SERVER, - start_time=environ.get( + start_time=request_meta.get( "opentelemetry-instrumentor-django.starttime_key" ), ) - attributes = collect_request_attributes(environ) + attributes = collect_request_attributes(request_meta) # pylint:disable=W0212 request._otel_labels = self._get_metric_labels_from_attributes( attributes @@ -215,7 +214,7 @@ def process_response(self, request, response): if metric_recorder is not None: # pylint:disable=W0212 metric_recorder.record_server_duration_range( - request._otel_start_time, time.time(), request._otel_labels + request._otel_start_time, time(), request._otel_labels ) except Exception as ex: # pylint: disable=W0703 _logger.warning("Error recording duration metrics: %s", ex) diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index b75a8cd0e9..21cbf53346 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -21,13 +21,13 @@ from django.test import Client from django.test.utils import setup_test_environment, teardown_test_environment -from opentelemetry.configuration import Configuration from opentelemetry.instrumentation.django import DjangoInstrumentor 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 ( @@ -64,7 +64,6 @@ def setUp(self): super().setUp() setup_test_environment() _django_instrumentor.instrument() - Configuration._reset() # pylint: disable=protected-access self.env_patch = patch.dict( "os.environ", { @@ -75,11 +74,11 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.django.middleware._DjangoMiddleware._excluded_urls", - Configuration()._excluded_urls("django"), + get_excluded_urls("DJANGO"), ) self.traced_patch = patch( "opentelemetry.instrumentation.django.middleware._DjangoMiddleware._traced_request_attrs", - Configuration()._traced_request_attrs("django"), + 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 bbc9268b9b..7ec050464f 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg @@ -42,6 +42,7 @@ 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 e9b1f16800..19b238fe1e 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -43,14 +43,13 @@ def on_get(self, req, resp): --- """ -import sys from logging import getLogger +from sys import exc_info import falcon import opentelemetry.instrumentation.wsgi as otel_wsgi -from opentelemetry import configuration, context, propagators, trace -from opentelemetry.configuration import Configuration +from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.falcon.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.utils import ( @@ -59,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__) @@ -68,8 +68,9 @@ def on_get(self, req, resp): _ENVIRON_TOKEN = "opentelemetry-falcon.token" _ENVIRON_EXC = "opentelemetry-falcon.exc" -cfg = configuration.Configuration() -_excluded_urls = cfg._excluded_urls("falcon") + +_excluded_urls = get_excluded_urls("FALCON") +_traced_request_attrs = get_traced_request_attrs("FALCON") class FalconInstrumentor(BaseInstrumentor): @@ -149,7 +150,7 @@ class _TraceMiddleware: def __init__(self, tracer=None, traced_request_attrs=None): self.tracer = tracer - self._traced_request_attrs = cfg._traced_request_attrs("falcon") + self._traced_request_attrs = _traced_request_attrs def process_request(self, req, resp): span = req.env.get(_ENVIRON_SPAN_KEY) @@ -186,7 +187,7 @@ def process_response( status = "404" reason = "NotFound" - exc_type, exc, _ = sys.exc_info() + exc_type, exc, _ = exc_info() if exc_type and not req_succeeded: if "HTTPNotFound" in exc_type.__name__: status = "404" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py index 73088d7611..b39b20ac38 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/tests/test_falcon.py @@ -16,10 +16,10 @@ from falcon import testing -from opentelemetry.configuration import Configuration 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 @@ -30,7 +30,6 @@ def setUp(self): FalconInstrumentor().instrument() self.app = make_app() # pylint: disable=protected-access - Configuration()._reset() self.env_patch = patch.dict( "os.environ", { @@ -41,7 +40,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.falcon._excluded_urls", - Configuration()._excluded_urls("falcon"), + get_excluded_urls("FALCON"), ) middleware = self.app._middleware[0][ # pylint:disable=W0212 0 @@ -49,7 +48,7 @@ def setUp(self): self.traced_patch = patch.object( middleware, "_traced_request_attrs", - Configuration()._traced_request_attrs("falcon"), + 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 6828ea1af4..388f0c23b6 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg @@ -40,6 +40,7 @@ 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 b938464065..2936da1875 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -11,17 +11,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from typing import Optional import fastapi from starlette.routing import Match -from opentelemetry.configuration import Configuration 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 -_excluded_urls = Configuration()._excluded_urls("fastapi") +_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 6d5a1b1808..fe6c27928a 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -19,8 +19,8 @@ from fastapi.testclient import TestClient import opentelemetry.instrumentation.fastapi as otel_fastapi -from opentelemetry.configuration import Configuration from opentelemetry.test.test_base import TestBase +from opentelemetry.util.http import get_excluded_urls class TestFastAPIManualInstrumentation(TestBase): @@ -31,7 +31,6 @@ def _create_app(self): def setUp(self): super().setUp() - Configuration()._reset() self.env_patch = patch.dict( "os.environ", {"OTEL_PYTHON_FASTAPI_EXCLUDED_URLS": "/exclude/123,healthzz"}, @@ -39,7 +38,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.fastapi._excluded_urls", - Configuration()._excluded_urls("fastapi"), + 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 bf98fb7880..6950b75b17 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-flask/setup.cfg @@ -40,8 +40,9 @@ 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-instrumentation-wsgi == 0.18.dev0 opentelemetry-api == 0.18.dev0 [options.extras_require] 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 b5045f3a72..6f94781843 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 @@ -52,10 +52,11 @@ def hello(): import flask import opentelemetry.instrumentation.wsgi as otel_wsgi -from opentelemetry import configuration, context, propagators, trace +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__) @@ -65,7 +66,7 @@ def hello(): _ENVIRON_TOKEN = "opentelemetry-flask.token" -_excluded_urls = configuration.Configuration()._excluded_urls("flask") +_excluded_urls = get_excluded_urls("FLASK") def get_default_span_name(): @@ -78,12 +79,12 @@ def get_default_span_name(): def _rewrapped_app(wsgi_app): - def _wrapped_app(environ, start_response): + def _wrapped_app(wrapped_app_environ, start_response): # We want to measure the time for route matching, etc. # In theory, we could start the span here and use # update_name later but that API is "highly discouraged" so # we better avoid it. - environ[_ENVIRON_STARTTIME_KEY] = time_ns() + wrapped_app_environ[_ENVIRON_STARTTIME_KEY] = time_ns() def _start_response(status, response_headers, *args, **kwargs): if not _excluded_urls.url_disabled(flask.request.url): @@ -102,7 +103,7 @@ def _start_response(status, response_headers, *args, **kwargs): return start_response(status, response_headers, *args, **kwargs) - return wsgi_app(environ, _start_response) + return wsgi_app(wrapped_app_environ, _start_response) return _wrapped_app @@ -112,10 +113,12 @@ def _before_request(): if _excluded_urls.url_disabled(flask.request.url): return - environ = flask.request.environ + flask_request_environ = flask.request.environ span_name = name_callback() token = context.attach( - propagators.extract(otel_wsgi.carrier_getter, environ) + propagators.extract( + otel_wsgi.carrier_getter, flask_request_environ + ) ) tracer = trace.get_tracer(__name__, __version__) @@ -123,10 +126,12 @@ def _before_request(): span = tracer.start_span( span_name, kind=trace.SpanKind.SERVER, - start_time=environ.get(_ENVIRON_STARTTIME_KEY), + start_time=flask_request_environ.get(_ENVIRON_STARTTIME_KEY), ) if span.is_recording(): - attributes = otel_wsgi.collect_request_attributes(environ) + attributes = otel_wsgi.collect_request_attributes( + flask_request_environ + ) if flask.request.url_rule: # For 404 that result from no route found, etc, we # don't have a url_rule. @@ -136,9 +141,9 @@ def _before_request(): activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() - environ[_ENVIRON_ACTIVATION_KEY] = activation - environ[_ENVIRON_SPAN_KEY] = span - environ[_ENVIRON_TOKEN] = token + flask_request_environ[_ENVIRON_ACTIVATION_KEY] = activation + flask_request_environ[_ENVIRON_SPAN_KEY] = span + flask_request_environ[_ENVIRON_TOKEN] = token return _before_request diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/base_test.py b/instrumentation/opentelemetry-instrumentation-flask/tests/base_test.py index c2bc646e1b..d989c66474 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/base_test.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/base_test.py @@ -15,14 +15,8 @@ from werkzeug.test import Client from werkzeug.wrappers import BaseResponse -from opentelemetry.configuration import Configuration - class InstrumentationTest: - def setUp(self): # pylint: disable=invalid-name - super().setUp() # pylint: disable=no-member - Configuration._reset() # pylint: disable=protected-access - @staticmethod def _hello_endpoint(helloid): if helloid == 500: diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 377ce88842..0e9ead6f50 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -17,10 +17,10 @@ from flask import Flask, request from opentelemetry import trace -from opentelemetry.configuration import Configuration 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 @@ -62,7 +62,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.flask._excluded_urls", - Configuration()._excluded_urls("flask"), + 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 b449fb34f5..09c1646e56 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg @@ -43,6 +43,7 @@ install_requires = 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 40894e2c62..66c3acd8cb 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -6,9 +6,10 @@ from pyramid.tweens import EXCVIEW import opentelemetry.instrumentation.wsgi as otel_wsgi -from opentelemetry import configuration, context, propagators, trace +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" @@ -22,7 +23,7 @@ _logger = getLogger(__name__) -_excluded_urls = configuration.Configuration()._excluded_urls("pyramid") +_excluded_urls = get_excluded_urls("PYRAMID") def includeme(config): @@ -44,10 +45,10 @@ def _insert_tween(config): def _before_traversal(event): request = event.request - environ = request.environ - span_name = otel_wsgi.get_default_span_name(environ) + request_environ = request.environ + span_name = otel_wsgi.get_default_span_name(request_environ) - enabled = environ.get(_ENVIRON_ENABLED_KEY) + enabled = request_environ.get(_ENVIRON_ENABLED_KEY) if enabled is None: _logger.warning( "Opentelemetry pyramid tween 'opentelemetry.instrumentation.pyramid.trace_tween_factory'" @@ -60,24 +61,24 @@ def _before_traversal(event): # Tracing not enabled, return return - start_time = environ.get(_ENVIRON_STARTTIME_KEY) + start_time = request_environ.get(_ENVIRON_STARTTIME_KEY) token = context.attach( - propagators.extract(otel_wsgi.carrier_getter, environ) + propagators.extract(otel_wsgi.carrier_getter, request_environ) ) tracer = trace.get_tracer(__name__, __version__) if request.matched_route: span_name = request.matched_route.pattern else: - span_name = otel_wsgi.get_default_span_name(environ) + span_name = otel_wsgi.get_default_span_name(request_environ) span = tracer.start_span( span_name, kind=trace.SpanKind.SERVER, start_time=start_time, ) if span.is_recording(): - attributes = otel_wsgi.collect_request_attributes(environ) + attributes = otel_wsgi.collect_request_attributes(request_environ) if request.matched_route: attributes["http.route"] = request.matched_route.pattern for key, value in attributes.items(): @@ -85,9 +86,9 @@ def _before_traversal(event): activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() - environ[_ENVIRON_ACTIVATION_KEY] = activation - environ[_ENVIRON_SPAN_KEY] = span - environ[_ENVIRON_TOKEN] = token + request_environ[_ENVIRON_ACTIVATION_KEY] = activation + request_environ[_ENVIRON_SPAN_KEY] = span + request_environ[_ENVIRON_TOKEN] = token def trace_tween_factory(handler, registry): diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py index 21a6a1ab95..70ab268c23 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/pyramid_base_test.py @@ -17,14 +17,8 @@ from werkzeug.test import Client from werkzeug.wrappers import BaseResponse -from opentelemetry.configuration import Configuration - class InstrumentationTest: - def setUp(self): # pylint: disable=invalid-name - super().setUp() # pylint: disable=no-member - Configuration._reset() # pylint: disable=protected-access - @staticmethod def _hello_endpoint(request): helloid = int(request.matchdict["helloid"]) diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py index 2affc3f5d3..9d037be37e 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/tests/test_programmatic.py @@ -17,10 +17,10 @@ from pyramid.config import Configurator from opentelemetry import trace -from opentelemetry.configuration import Configuration from opentelemetry.instrumentation.pyramid import PyramidInstrumentor 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 @@ -62,7 +62,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.pyramid.callbacks._excluded_urls", - Configuration()._excluded_urls("pyramid"), + 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 4b2123d9b7..8f52b4741d 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg @@ -40,6 +40,7 @@ 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 1725123b6d..d595beadcf 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -11,17 +11,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from typing import Optional from starlette import applications from starlette.routing import Match -from opentelemetry.configuration import Configuration from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.starlette.version import __version__ # noqa +from opentelemetry.util.http import get_excluded_urls -_excluded_urls = Configuration()._excluded_urls("starlette") +_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 1729741363..56116c5a06 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -21,8 +21,8 @@ from starlette.testclient import TestClient import opentelemetry.instrumentation.starlette as otel_starlette -from opentelemetry.configuration import Configuration from opentelemetry.test.test_base import TestBase +from opentelemetry.util.http import get_excluded_urls class TestStarletteManualInstrumentation(TestBase): @@ -33,7 +33,6 @@ def _create_app(self): def setUp(self): super().setUp() - Configuration()._reset() self.env_patch = patch.dict( "os.environ", {"OTEL_PYTHON_STARLETTE_EXCLUDED_URLS": "/exclude/123,healthzz"}, @@ -41,7 +40,7 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.starlette._excluded_urls", - Configuration()._excluded_urls("starlette"), + 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 035572e32f..69b32a3e3f 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 5806b3664c..f030c65801 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -35,18 +35,15 @@ def get(self): tornado.ioloop.IOLoop.current().start() """ -import inspect -import typing from collections import namedtuple -from functools import partial, wraps +from functools import partial from logging import getLogger import tornado.web import wrapt -from tornado.routing import Rule from wrapt import wrap_function_wrapper -from opentelemetry import configuration, context, propagators, trace +from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.tornado.version import __version__ from opentelemetry.instrumentation.utils import ( @@ -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 @@ -65,10 +63,9 @@ def get(self): _HANDLER_CONTEXT_KEY = "_otel_trace_context_key" _OTEL_PATCHED_KEY = "_otel_patched_key" -cfg = configuration.Configuration() -_excluded_urls = cfg._excluded_urls("tornado") -_traced_attrs = cfg._traced_request_attrs("tornado") +_excluded_urls = get_excluded_urls("TORNADO") +_traced_request_attrs = get_traced_request_attrs("TORNADO") carrier_getter = DictGetter() @@ -186,7 +183,9 @@ def _get_attributes_from_request(request): if request.remote_ip: attrs["net.peer.ip"] = request.remote_ip - return extract_attributes_from_object(request, _traced_attrs, attrs) + return extract_attributes_from_object( + request, _traced_request_attrs, attrs + ) def _get_operation_name(handler, request): diff --git a/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py index 3bdf007717..6d2c04f89f 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py @@ -18,7 +18,6 @@ from tornado.testing import AsyncHTTPTestCase from opentelemetry import trace -from opentelemetry.configuration import Configuration from opentelemetry.instrumentation.tornado import ( TornadoInstrumentor, patch_handler_class, @@ -26,6 +25,7 @@ ) 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, @@ -45,7 +45,6 @@ def setUp(self): TornadoInstrumentor().instrument() super().setUp() # pylint: disable=protected-access - Configuration()._reset() self.env_patch = patch.dict( "os.environ", { @@ -56,11 +55,11 @@ def setUp(self): self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.tornado._excluded_urls", - Configuration()._excluded_urls("tornado"), + get_excluded_urls("TORNADO"), ) self.traced_patch = patch( - "opentelemetry.instrumentation.tornado._traced_attrs", - Configuration()._traced_request_attrs("tornado"), + "opentelemetry.instrumentation.tornado._traced_request_attrs", + get_traced_request_attrs("TORNADO"), ) self.exclude_patch.start() self.traced_patch.start() diff --git a/tox.ini b/tox.ini index 87462e4c87..c4ea92b463 100644 --- a/tox.ini +++ b/tox.ini @@ -138,6 +138,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 docs @@ -193,6 +197,7 @@ changedir = 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 @@ -211,6 +216,7 @@ commands_pre = grpc: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc[test] + falcon,flask,django,pyramid,tornado,starlette,fastapi: pip install {toxinidir}/util/opentelemetry-util-http wsgi,falcon,flask,django,pyramid: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi asgi,starlette,fastapi: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi @@ -274,7 +280,8 @@ commands_pre = 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 @@ -288,6 +295,12 @@ deps = -r {toxinidir}/docs-requirements.txt pytest +commands_pre = + python -m pip install {toxinidir}/opentelemetry-python-core/opentelemetry-api + python -m pip install {toxinidir}/opentelemetry-python-core/opentelemetry-sdk + python -m pip install {toxinidir}/opentelemetry-python-core/opentelemetry-instrumentation + python -m pip install {toxinidir}/util/opentelemetry-util-http + changedir = docs commands = @@ -314,6 +327,7 @@ 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 {toxinidir}/util/opentelemetry-util-http python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi[test] diff --git a/util/opentelemetry-util-http/README.rst b/util/opentelemetry-util-http/README.rst new file mode 100644 index 0000000000..c7b58b5b42 --- /dev/null +++ b/util/opentelemetry-util-http/README.rst @@ -0,0 +1,72 @@ +OpenTelemetry Util HTTP +======================= + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-util-http.svg + :target: https://pypi.org/project/opentelemetry-util-http/ + + +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-util-http + + +Usage (Quart) +------------- + +.. code-block:: python + + from quart import Quart + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + + app = Quart(__name__) + app.asgi_app = OpenTelemetryMiddleware(app.asgi_app) + + @app.route("/") + async def hello(): + return "Hello!" + + if __name__ == "__main__": + app.run(debug=True) + + +Usage (Django 3.0) +------------------ + +Modify the application's ``asgi.py`` file as shown below. + +.. code-block:: python + + import os + from django.core.asgi import get_asgi_application + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'asgi_example.settings') + + application = get_asgi_application() + application = OpenTelemetryMiddleware(application) + + +Usage (Raw ASGI) +---------------- + +.. code-block:: python + + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + + app = ... # An ASGI application. + app = OpenTelemetryMiddleware(app) + + +References +---------- + +* `OpenTelemetry Project `_ diff --git a/util/opentelemetry-util-http/setup.cfg b/util/opentelemetry-util-http/setup.cfg new file mode 100644 index 0000000000..e304fea9d8 --- /dev/null +++ b/util/opentelemetry-util-http/setup.cfg @@ -0,0 +1,51 @@ +# 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-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/util/opentelemetry-util-http +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.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +python_requires = >=3.5 +package_dir= + =src +packages=find_namespace: +install_requires = + opentelemetry-api == 0.18.dev0 + opentelemetry-instrumentation == 0.18.dev0 + asgiref ~= 3.0 + +[options.extras_require] +test = + opentelemetry-test == 0.18.dev0 + +[options.packages.find] +where = src diff --git a/util/opentelemetry-util-http/setup.py b/util/opentelemetry-util-http/setup.py new file mode 100644 index 0000000000..1202dd07e3 --- /dev/null +++ b/util/opentelemetry-util-http/setup.py @@ -0,0 +1,26 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os + +import setuptools + +BASE_DIR = os.path.dirname(__file__) +VERSION_FILENAME = os.path.join( + BASE_DIR, "src", "opentelemetry", "util", "http", "version.py" +) +PACKAGE_INFO = {} +with open(VERSION_FILENAME) as f: + exec(f.read(), PACKAGE_INFO) + +setuptools.setup(version=PACKAGE_INFO["__version__"]) 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/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py new file mode 100644 index 0000000000..ebb75f6c11 --- /dev/null +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -0,0 +1,15 @@ +# 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.18.dev0" diff --git a/util/opentelemetry-util-http/tests/__init__.py b/util/opentelemetry-util-http/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2