From b246cce2d08cca111f51d970d921cd12b79abbd7 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 3 Feb 2021 23:26:17 -0600 Subject: [PATCH] Put asgi and wsgi back as instrumentations --- docs-requirements.txt | 7 + docs/instrumentation/asgi/asgi.rst | 9 + docs/instrumentation/wsgi/wsgi.rst | 7 + eachdist.ini | 2 + .../exporter/datadog/exporter.py | 2 +- .../tests/test_datadog_exporter.py | 2 +- .../README.rst | 71 +++++++ .../setup.py | 26 +++ .../instrumentation}/asgi/__init__.py | 8 +- .../instrumentation}/asgi/version.py | 0 .../tests}/__init__.py | 0 .../tests}/test_asgi_middleware.py | 2 +- .../setup.cfg | 1 + .../instrumentation/django/middleware.py | 8 +- .../setup.cfg | 1 + .../instrumentation/falcon/__init__.py | 4 +- .../setup.cfg | 1 + .../instrumentation/fastapi/__init__.py | 2 +- .../setup.cfg | 1 + .../instrumentation/flask/__init__.py | 2 +- .../setup.cfg | 1 + .../instrumentation/pyramid/callbacks.py | 2 +- .../setup.cfg | 1 + .../instrumentation/starlette/__init__.py | 2 +- .../LICENSE | 201 ++++++++++++++++++ .../MANIFEST.in | 9 + .../README.rst | 26 +++ .../setup.cfg | 50 +++++ .../setup.py | 26 +++ .../instrumentation}/wsgi/__init__.py | 12 +- .../instrumentation}/wsgi/version.py | 0 .../tests}/__init__.py | 0 .../tests}/test_getter.py | 2 +- .../tests}/test_wsgi_middleware.py | 2 +- scripts/coverage.sh | 1 + tox.ini | 18 +- util/opentelemetry-util-http/README.rst | 6 +- 37 files changed, 485 insertions(+), 30 deletions(-) create mode 100644 docs/instrumentation/asgi/asgi.rst create mode 100644 docs/instrumentation/wsgi/wsgi.rst create mode 100644 instrumentation/opentelemetry-instrumentation-asgi/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-asgi/setup.py rename {util/opentelemetry-util-http/src/opentelemetry/util/http => instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation}/asgi/__init__.py (96%) rename {util/opentelemetry-util-http/src/opentelemetry/util/http => instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation}/asgi/version.py (100%) rename {util/opentelemetry-util-http/tests/asgi => instrumentation/opentelemetry-instrumentation-asgi/tests}/__init__.py (100%) rename {util/opentelemetry-util-http/tests/asgi => instrumentation/opentelemetry-instrumentation-asgi/tests}/test_asgi_middleware.py (99%) create mode 100644 instrumentation/opentelemetry-instrumentation-wsgi/LICENSE create mode 100644 instrumentation/opentelemetry-instrumentation-wsgi/MANIFEST.in create mode 100644 instrumentation/opentelemetry-instrumentation-wsgi/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg create mode 100644 instrumentation/opentelemetry-instrumentation-wsgi/setup.py rename {util/opentelemetry-util-http/src/opentelemetry/util/http => instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation}/wsgi/__init__.py (95%) rename {util/opentelemetry-util-http/src/opentelemetry/util/http => instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation}/wsgi/version.py (100%) rename {util/opentelemetry-util-http/tests/wsgi => instrumentation/opentelemetry-instrumentation-wsgi/tests}/__init__.py (100%) rename {util/opentelemetry-util-http/tests/wsgi => instrumentation/opentelemetry-instrumentation-wsgi/tests}/test_getter.py (94%) rename {util/opentelemetry-util-http/tests/wsgi => instrumentation/opentelemetry-instrumentation-wsgi/tests}/test_wsgi_middleware.py (99%) diff --git a/docs-requirements.txt b/docs-requirements.txt index 472b32512a..dc1cbc7790 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -2,11 +2,18 @@ sphinx~=2.4 sphinx-rtd-theme~=0.4 sphinx-autodoc-typehints~=1.10.2 +# Need to install the api/sdk in the venv for autodoc. Modifying sys.path +# doesn't work for pkg_resources. +-e "git+https://github.com/open-telemetry/opentelemetry-python.git#egg=opentelemetry-api&subdirectory=opentelemetry-api" +-e "git+https://github.com/open-telemetry/opentelemetry-python.git#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk" + # Required by opentelemetry-instrumentation fastapi~=0.58.1 psutil~=5.7.0 pymemcache~=1.3 +-e "git+https://github.com/open-telemetry/opentelemetry-python.git#egg=opentelemetry-instrumentation&subdirectory=opentelemetry-instrumentation" + # Required by conf django>=2.2 diff --git a/docs/instrumentation/asgi/asgi.rst b/docs/instrumentation/asgi/asgi.rst new file mode 100644 index 0000000000..b988e4de43 --- /dev/null +++ b/docs/instrumentation/asgi/asgi.rst @@ -0,0 +1,9 @@ +.. include:: ../../../instrumentation/opentelemetry-instrumentation-asgi/README.rst + +API +--- + +.. automodule:: opentelemetry.instrumentation.asgi + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/instrumentation/wsgi/wsgi.rst b/docs/instrumentation/wsgi/wsgi.rst new file mode 100644 index 0000000000..39ad5ffd58 --- /dev/null +++ b/docs/instrumentation/wsgi/wsgi.rst @@ -0,0 +1,7 @@ +OpenTelemetry WSGI Instrumentation +================================== + +.. automodule:: opentelemetry.instrumentation.wsgi + :members: + :undoc-members: + :show-inheritance: diff --git a/eachdist.ini b/eachdist.ini index 71e854068b..65e6fc501e 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -8,7 +8,9 @@ ignore= sortfirst= util/opentelemetry-util-http + instrumentation/opentelemetry-instrumentation-wsgi instrumentation/opentelemetry-instrumentation-dbapi + instrumentation/opentelemetry-instrumentation-asgi instrumentation/opentelemetry-instrumentation-botocore instrumentation/* exporter/* diff --git a/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py b/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py index fdf443d0cd..129e0d0c48 100644 --- a/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py +++ b/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py @@ -51,7 +51,7 @@ "opentelemetry.instrumentation.redis": DatadogSpanTypes.REDIS, "opentelemetry.instrumentation.requests": DatadogSpanTypes.HTTP, "opentelemetry.instrumentation.sqlalchemy": DatadogSpanTypes.SQL, - "opentelemetry.util.http.wsgi": DatadogSpanTypes.WEB, + "opentelemetry.instrumentation.wsgi": DatadogSpanTypes.WEB, } diff --git a/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py b/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py index 40070c147e..4a576c5de1 100644 --- a/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py +++ b/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py @@ -334,7 +334,7 @@ def test_span_types(self): "opentelemetry.instrumentation.redis", "opentelemetry.instrumentation.requests", "opentelemetry.instrumentation.sqlalchemy", - "opentelemetry.util.http.wsgi", + "opentelemetry.instrumentation.wsgi", ] for index, instrumentation in enumerate(test_instrumentations): diff --git a/instrumentation/opentelemetry-instrumentation-asgi/README.rst b/instrumentation/opentelemetry-instrumentation-asgi/README.rst new file mode 100644 index 0000000000..3eb8e2dda7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-asgi/README.rst @@ -0,0 +1,71 @@ +OpenTelemetry ASGI Instrumentation +================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-asgi.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-asgi/ + + +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. + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-asgi + + +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/instrumentation/opentelemetry-instrumentation-asgi/setup.py b/instrumentation/opentelemetry-instrumentation-asgi/setup.py new file mode 100644 index 0000000000..3369352fe1 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-asgi/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", "instrumentation", "asgi", "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/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py similarity index 96% rename from util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/__init__.py rename to instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 2cdb054d08..f52e5a4067 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -13,9 +13,9 @@ # limitations under the License. """ -The opentelemetry.util.http.asgi package provides an ASGI middleware that can -be used on any ASGI framework (such as Django-channels / Quart) to track -requests timing through OpenTelemetry. +The opentelemetry-instrumentation-asgi 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 typing @@ -26,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/util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py similarity index 100% rename from util/opentelemetry-util-http/src/opentelemetry/util/http/asgi/version.py rename to instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py diff --git a/util/opentelemetry-util-http/tests/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/__init__.py similarity index 100% rename from util/opentelemetry-util-http/tests/asgi/__init__.py rename to instrumentation/opentelemetry-instrumentation-asgi/tests/__init__.py diff --git a/util/opentelemetry-util-http/tests/asgi/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py similarity index 99% rename from util/opentelemetry-util-http/tests/asgi/test_asgi_middleware.py rename to instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index 264cbf2c8c..7c4ae20a77 100644 --- a/util/opentelemetry-util-http/tests/asgi/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -16,7 +16,7 @@ import unittest import unittest.mock as mock -import opentelemetry.util.http.asgi as otel_asgi +import opentelemetry.instrumentation.asgi as otel_asgi from opentelemetry import trace as trace_api from opentelemetry.test.asgitestutil import ( AsgiTestBase, diff --git a/instrumentation/opentelemetry-instrumentation-django/setup.cfg b/instrumentation/opentelemetry-instrumentation-django/setup.cfg index 33f41f88c9..6528f616c0 100644 --- a/instrumentation/opentelemetry-instrumentation-django/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-django/setup.cfg @@ -41,6 +41,7 @@ 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/middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py index 64be5c53f0..a167cb9ab4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py @@ -20,14 +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.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 ( +from opentelemetry.instrumentation.wsgi import ( add_response_attributes, carrier_getter, collect_request_attributes, ) +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 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg b/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg index ceb07f7f4e..7ec050464f 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-falcon/setup.cfg @@ -41,6 +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 51ecf0d645..19b238fe1e 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-util-http, +in Falcon applications. In addition to opentelemetry-instrumentation-wsgi, it supports falcon-specific features such as: * The Falcon resource and method name is used as the Span name. @@ -48,7 +48,7 @@ def on_get(self, req, resp): import falcon -import opentelemetry.util.http.wsgi as otel_wsgi +import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.falcon.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg b/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg index 7e83ba60a1..388f0c23b6 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-fastapi/setup.cfg @@ -39,6 +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] 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 7c6429ba32..2936da1875 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -15,9 +15,9 @@ import fastapi from starlette.routing import Match +from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.util.http import get_excluded_urls -from opentelemetry.util.http.asgi import OpenTelemetryMiddleware _excluded_urls = get_excluded_urls("FASTAPI") diff --git a/instrumentation/opentelemetry-instrumentation-flask/setup.cfg b/instrumentation/opentelemetry-instrumentation-flask/setup.cfg index f99dbe81fb..6950b75b17 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-flask/setup.cfg @@ -42,6 +42,7 @@ install_requires = flask ~= 1.0 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 1f8adb3d00..6f94781843 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -51,7 +51,7 @@ def hello(): import flask -import opentelemetry.util.http.wsgi as otel_wsgi +import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.flask.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg b/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg index 240ebf8054..09c1646e56 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-pyramid/setup.cfg @@ -42,6 +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 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 0aa8a02371..66c3acd8cb 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -5,7 +5,7 @@ from pyramid.settings import asbool from pyramid.tweens import EXCVIEW -import opentelemetry.util.http.wsgi as otel_wsgi +import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, propagators, trace from opentelemetry.instrumentation.pyramid.version import __version__ from opentelemetry.util import time_ns diff --git a/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg b/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg index 4977126ce9..8f52b4741d 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-starlette/setup.cfg @@ -39,6 +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] 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 f222225e76..d595beadcf 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -15,9 +15,9 @@ from starlette import applications from starlette.routing import Match +from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.util.http import get_excluded_urls -from opentelemetry.util.http.asgi import OpenTelemetryMiddleware _excluded_urls = get_excluded_urls("STARLETTE") diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/LICENSE b/instrumentation/opentelemetry-instrumentation-wsgi/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-wsgi/LICENSE @@ -0,0 +1,201 @@ + 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 new file mode 100644 index 0000000000..aed3e33273 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-wsgi/MANIFEST.in @@ -0,0 +1,9 @@ +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 new file mode 100644 index 0000000000..c3f06bfedb --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-wsgi/README.rst @@ -0,0 +1,26 @@ +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/instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg b/instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg new file mode 100644 index 0000000000..8085f59187 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-wsgi/setup.cfg @@ -0,0 +1,50 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +[metadata] +name = opentelemetry-instrumentation-wsgi +description = WSGI Middleware 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/main/instrumentation/opentelemetry-instrumentation-wsgi +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 + +[options.extras_require] +test = + opentelemetry-test == 0.18.dev0 + +[options.packages.find] +where = src diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/setup.py b/instrumentation/opentelemetry-instrumentation-wsgi/setup.py new file mode 100644 index 0000000000..fb4ffa7437 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-wsgi/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", "instrumentation", "wsgi", "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/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py similarity index 95% rename from util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/__init__.py rename to instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 9b7308b64d..c336a1320b 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -21,7 +21,7 @@ .. code-block:: python from flask import Flask - from opentelemetry.util.http.wsgi import OpenTelemetryMiddleware + from opentelemetry.instrumentation.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.util.http.wsgi import OpenTelemetryMiddleware + from opentelemetry.instrumentation.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/" @@ -233,9 +233,9 @@ def __call__(self, environ, start_response): raise -# 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). +# 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/util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py similarity index 100% rename from util/opentelemetry-util-http/src/opentelemetry/util/http/wsgi/version.py rename to instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py diff --git a/util/opentelemetry-util-http/tests/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py similarity index 100% rename from util/opentelemetry-util-http/tests/wsgi/__init__.py rename to instrumentation/opentelemetry-instrumentation-wsgi/tests/__init__.py diff --git a/util/opentelemetry-util-http/tests/wsgi/test_getter.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py similarity index 94% rename from util/opentelemetry-util-http/tests/wsgi/test_getter.py rename to instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py index 937f01b629..80cf6b1ecd 100644 --- a/util/opentelemetry-util-http/tests/wsgi/test_getter.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py @@ -14,7 +14,7 @@ from unittest import TestCase -from opentelemetry.util.http.wsgi import CarrierGetter +from opentelemetry.instrumentation.wsgi import CarrierGetter class TestCarrierGetter(TestCase): diff --git a/util/opentelemetry-util-http/tests/wsgi/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py similarity index 99% rename from util/opentelemetry-util-http/tests/wsgi/test_wsgi_middleware.py rename to instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py index b058a86727..d5168e3280 100644 --- a/util/opentelemetry-util-http/tests/wsgi/test_wsgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py @@ -18,7 +18,7 @@ import wsgiref.util as wsgiref_util from urllib.parse import urlsplit -import opentelemetry.util.http.wsgi as otel_wsgi +import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import trace as trace_api from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.trace.status import StatusCode diff --git a/scripts/coverage.sh b/scripts/coverage.sh index 15960a3108..8055adb0de 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -20,6 +20,7 @@ coverage erase cov exporter/opentelemetry-exporter-datadog cov instrumentation/opentelemetry-instrumentation-flask cov instrumentation/opentelemetry-instrumentation-requests +cov instrumentation/opentelemetry-instrumentation-wsgi # aiohttp is only supported on Python 3.5+. if [ ${PYTHON_VERSION_INFO[1]} -gt 4 ]; then diff --git a/tox.ini b/tox.ini index d9feb0801f..2015933463 100644 --- a/tox.ini +++ b/tox.ini @@ -94,6 +94,10 @@ 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 @@ -102,6 +106,10 @@ 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 @@ -160,6 +168,7 @@ 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 @@ -187,6 +196,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 @@ -206,7 +216,8 @@ commands_pre = grpc: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc[test] - falcon,flask,django,pyramid,starlette,fastapi,tornado: 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 asyncpg: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg @@ -228,6 +239,7 @@ 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] @@ -264,10 +276,10 @@ 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 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 @@ -315,7 +327,9 @@ commands_pre = 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] 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/util/opentelemetry-util-http/README.rst b/util/opentelemetry-util-http/README.rst index 3ec70435d9..c7b58b5b42 100644 --- a/util/opentelemetry-util-http/README.rst +++ b/util/opentelemetry-util-http/README.rst @@ -25,7 +25,7 @@ Usage (Quart) .. code-block:: python from quart import Quart - from opentelemetry.util.http.asgi import OpenTelemetryMiddleware + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware app = Quart(__name__) app.asgi_app = OpenTelemetryMiddleware(app.asgi_app) @@ -47,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.util.http.asgi import OpenTelemetryMiddleware + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'asgi_example.settings') @@ -60,7 +60,7 @@ Usage (Raw ASGI) .. code-block:: python - from opentelemetry.util.http.asgi import OpenTelemetryMiddleware + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware app = ... # An ASGI application. app = OpenTelemetryMiddleware(app)